pike.git/src/code/sparc.c:1:
/*
|| This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
- || $Id: sparc.c,v 1.44 2005/06/23 15:09:42 grubba Exp $
+ || $Id: sparc.c,v 1.45 2005/06/23 16:30:02 grubba Exp $
*/
/*
* Machine code generator for sparc.
*
* Henrik Grubbström 20010720
*/
#include "global.h"
#include "svalue.h"
pike.git/src/code/sparc.c:239:
#define SPARC_REG_PIKE_MARK_SP SPARC_REG_L3
#define SPARC_REG_PIKE_OBJ SPARC_REG_L4
#define SPARC_REG_PIKE_DEBUG SPARC_REG_L7
#define SPARC_REG_SP SPARC_REG_O6
#define SPARC_REG_PC SPARC_REG_O7
/*
* Code generator state.
*/
unsigned INT32 sparc_codegen_state = 0;
+ static int sparc_pike_sp_bias = 0;
ptrdiff_t sparc_last_pc = 0;
#ifdef PIKE_BYTECODE_SPARC64
#define PIKE_LDPTR SPARC_LDX
#define PIKE_STPTR SPARC_STX
#else /* !PIKE_BYTECODE_SPARC64 */
#define PIKE_LDPTR SPARC_LDUW
#define PIKE_STPTR SPARC_STW
#endif /* PIKE_BYTECODE_SPARC64 */
pike.git/src/code/sparc.c:274:
} \
} while(0)
#define LOAD_PIKE_SP() do { \
if (!(sparc_codegen_state & SPARC_CODEGEN_SP_IS_SET)) { \
LOAD_PIKE_INTERPRETER(); \
/* lduw [ %ip, %offset(Pike_interpreter, stack_pointer) ], %l2 */ \
PIKE_LDPTR(SPARC_REG_PIKE_SP, SPARC_REG_PIKE_IP, \
OFFSETOF(Pike_interpreter, stack_pointer), 1); \
sparc_codegen_state |= SPARC_CODEGEN_SP_IS_SET; \
+ sparc_pike_sp_bias = 0; \
+ } else if (sparc_pike_sp_bias > 0xf00) { \
+ /* Make sure there's always space for at least 256 bytes. */ \
+ SPARC_ADD(SPARC_REG_PIKE_SP, SPARC_REG_PIKE_SP, \
+ sparc_pike_sp_bias, 1); \
+ sparc_pike_sp_bias = 0; \
+ sparc_codegen_state |= SPARC_CODEGEN_SP_NEEDS_STORE; \
} \
} while(0)
#define LOAD_PIKE_MARK_SP() do { \
if (!(sparc_codegen_state & SPARC_CODEGEN_MARK_SP_IS_SET)) { \
LOAD_PIKE_INTERPRETER(); \
/* lduw [ %ip, %offset(Pike_interpreter, mark_stack_pointer) ], %l2 */ \
PIKE_LDPTR(SPARC_REG_PIKE_MARK_SP, SPARC_REG_PIKE_IP, \
OFFSETOF(Pike_interpreter, mark_stack_pointer), 1); \
sparc_codegen_state |= SPARC_CODEGEN_MARK_SP_IS_SET; \
} \
} while(0)
#define SPARC_FLUSH_UNSTORED() do { \
-
+ if (sparc_pike_sp_bias) { \
+ SPARC_ADD(SPARC_REG_PIKE_SP, SPARC_REG_PIKE_SP, \
+ sparc_pike_sp_bias, 1); \
+ sparc_pike_sp_bias = 0; \
+ sparc_codegen_state |= SPARC_CODEGEN_SP_NEEDS_STORE; \
+ } \
if (sparc_codegen_state & SPARC_CODEGEN_MARK_SP_NEEDS_STORE) { \
/* stw %pike_mark_sp, [ %ip, %offset(Pike_interpreter, mark_stack_pointer) ] */ \
PIKE_STPTR(SPARC_REG_PIKE_MARK_SP, SPARC_REG_PIKE_IP, \
OFFSETOF(Pike_interpreter, mark_stack_pointer), 1); \
sparc_codegen_state &= ~SPARC_CODEGEN_MARK_SP_NEEDS_STORE; \
} \
if (sparc_codegen_state & SPARC_CODEGEN_SP_NEEDS_STORE) { \
/* stw %pike_sp, [ %ip, %offset(Pike_interpreter, stack_pointer) ] */ \
PIKE_STPTR(SPARC_REG_PIKE_SP, SPARC_REG_PIKE_IP, \
OFFSETOF(Pike_interpreter, stack_pointer), 1); \
pike.git/src/code/sparc.c:392:
static void sparc_incr_mark_sp(int delta)
{
LOAD_PIKE_MARK_SP();
/* add %pike_mark_sp, %pike_mark_sp, 4 * delta */
SPARC_ADD(SPARC_REG_PIKE_MARK_SP, SPARC_REG_PIKE_MARK_SP,
sizeof(void *)*delta, 1);
sparc_codegen_state |= SPARC_CODEGEN_MARK_SP_NEEDS_STORE;
}
- static void sparc_mark(int off)
+ static void sparc_mark(ptrdiff_t off)
{
LOAD_PIKE_SP();
LOAD_PIKE_MARK_SP();
- if (off) {
+
off *= sizeof(struct svalue);
-
+ off += sparc_pike_sp_bias;
+ if (off) {
if ((-4096 <= off) && (off < 4096)) {
/* add %i0, %pike_sp, off */
SPARC_ADD(SPARC_REG_I0, SPARC_REG_PIKE_SP, off, 1);
} else {
SET_REG(SPARC_REG_I0, off);
/* add %i0, %pike_sp, %i0 */
SPARC_ADD(SPARC_REG_I0, SPARC_REG_PIKE_SP, SPARC_REG_I0, 0);
}
/* stw %i0, [ %pike_mark_sp, %g0 ] */
PIKE_STPTR(SPARC_REG_I0, SPARC_REG_PIKE_MARK_SP, SPARC_REG_G0, 0);
pike.git/src/code/sparc.c:429:
LOAD_PIKE_SP();
#ifdef PIKE_DEBUG
if (sizeof(struct svalue) > 8) {
size_t e;
for (e = 4; e < sizeof(struct svalue); e += 4) {
/* Pad until we reach the anything field. */
if (e == OFFSETOF(svalue, u.integer)) continue;
/* stw %g0, [ %pike_sp, e ] */
- SPARC_STW(SPARC_REG_G0, SPARC_REG_PIKE_SP, e, 1);
+ SPARC_STW(SPARC_REG_G0, SPARC_REG_PIKE_SP, sparc_pike_sp_bias + e, 1);
}
}
#endif /* PIKE_DEBUG */
if (x) {
SET_REG(SPARC_REG_I1, x);
reg = SPARC_REG_I1;
}
if (sizeof(INT_TYPE) == 4) {
- SPARC_STW(reg, SPARC_REG_PIKE_SP, OFFSETOF(svalue, u.integer), 1);
+ SPARC_STW(reg, SPARC_REG_PIKE_SP,
+ sparc_pike_sp_bias + OFFSETOF(svalue, u.integer), 1);
} else {
- SPARC_STX(reg, SPARC_REG_PIKE_SP, OFFSETOF(svalue, u.integer), 1);
+ SPARC_STX(reg, SPARC_REG_PIKE_SP,
+ sparc_pike_sp_bias + OFFSETOF(svalue, u.integer), 1);
}
if (x != type_word) {
SET_REG(SPARC_REG_I1, type_word);
}
/* This is safe since type_word is never zero. */
/* stw %i1, [ %pike_sp ] */
- SPARC_STW(SPARC_REG_I1, SPARC_REG_PIKE_SP, 0, 1);
- /* add %pike_sp, %pike_sp, sizeof(struct svalue) */
- SPARC_ADD(SPARC_REG_PIKE_SP, SPARC_REG_PIKE_SP, sizeof(struct svalue), 1);
+ SPARC_STW(SPARC_REG_I1, SPARC_REG_PIKE_SP, sparc_pike_sp_bias, 1);
+ sparc_pike_sp_bias += sizeof(struct svalue);
sparc_codegen_state |= SPARC_CODEGEN_SP_NEEDS_STORE;
}
static void sparc_clear_string_subtype(void)
{
LOAD_PIKE_SP();
/* lduh [ %pike_sp, %g0 ], %i0 */
- SPARC_LDUH(SPARC_REG_I0, SPARC_REG_PIKE_SP, OFFSETOF(svalue, type), 1);
+ SPARC_LDUH(SPARC_REG_I0, SPARC_REG_PIKE_SP,
+ sparc_pike_sp_bias + OFFSETOF(svalue, type), 1);
/* subcc %g0, %i0, 8 */
SPARC_SUBcc(SPARC_REG_G0, SPARC_REG_I0, PIKE_T_INT, 1);
/* be,a .+8 */
SPARC_BE(8, 1);
/* sth %g0, [ %pike_sp, 2 ] */
- SPARC_STH(SPARC_REG_G0, SPARC_REG_PIKE_SP, OFFSETOF(svalue, subtype), 1);
+ SPARC_STH(SPARC_REG_G0, SPARC_REG_PIKE_SP,
+ sparc_pike_sp_bias + OFFSETOF(svalue, subtype), 1);
}
static void sparc_push_lfun(unsigned int no)
{
LOAD_PIKE_FP();
LOAD_PIKE_SP();
/* lduw [ %pike_fp, %offset(pike_frame, current_object) ], %pike_obj */
PIKE_LDPTR(SPARC_REG_PIKE_OBJ, SPARC_REG_PIKE_FP,
OFFSETOF(pike_frame, current_object), 1);
/* stw %pike_obj, [ %pike_sp, %offset(svalue, u.object) ] */
PIKE_STPTR(SPARC_REG_PIKE_OBJ, SPARC_REG_PIKE_SP,
- OFFSETOF(svalue, u.object), 1);
+ sparc_pike_sp_bias + OFFSETOF(svalue, u.object), 1);
/* lduw [ %pike_obj, %offset(object, refs) ], %i0 */
SPARC_LDUW(SPARC_REG_I0, SPARC_REG_PIKE_OBJ,
OFFSETOF(object, refs), 1);
/* add %i0, 1, %i0 */
SPARC_ADD(SPARC_REG_I0, SPARC_REG_I0, 1, 1);
/* stw %i0, [ %pike_obj, %offset(object, refs) ] */
SPARC_STW(SPARC_REG_I0, SPARC_REG_PIKE_OBJ,
OFFSETOF(object, refs), 1);
/* lduh [ %pike_fp, %offset(pike_frame, context.identifier_level ], %i1 */
SPARC_LDUH(SPARC_REG_I1, SPARC_REG_PIKE_FP,
OFFSETOF(pike_frame, context.identifier_level), 1);
SET_REG(SPARC_REG_I2, (no & 0xffff) | (PIKE_T_FUNCTION << 16));
/* add %i1, %i2, %i1 */
SPARC_ADD(SPARC_REG_I1, SPARC_REG_I1, SPARC_REG_I2, 0);
/* stw %i1, [ %pike_sp, %g0 ] */
- SPARC_STW(SPARC_REG_I1, SPARC_REG_PIKE_SP, SPARC_REG_G0, 0);
- /* add %pike_sp, sizeof(struct svalue), %pike_sp */
- SPARC_ADD(SPARC_REG_PIKE_SP, SPARC_REG_PIKE_SP, sizeof(struct svalue), 1);
+ SPARC_STW(SPARC_REG_I1, SPARC_REG_PIKE_SP, sparc_pike_sp_bias, 1);
+ sparc_pike_sp_bias += sizeof(struct svalue);
sparc_codegen_state |= SPARC_CODEGEN_SP_NEEDS_STORE;
}
void sparc_local_lvalue(unsigned int no)
{
LOAD_PIKE_SP();
LOAD_PIKE_FP();
SET_REG(SPARC_REG_I0, T_SVALUE_PTR);
/* sth %i0, [ %pike_sp, %g0 ] */
- SPARC_STH(SPARC_REG_I0, SPARC_REG_PIKE_SP, SPARC_REG_G0, 0);
+ SPARC_STH(SPARC_REG_I0, SPARC_REG_PIKE_SP, sparc_pike_sp_bias, 1);
SET_REG(SPARC_REG_I0, T_VOID);
no *= sizeof(struct svalue);
if (no < 4096) {
/* lduw [ %pike_fp, %offset(pike_frame, locals) ], %i2 */
PIKE_LDPTR(SPARC_REG_I2, SPARC_REG_PIKE_FP,
OFFSETOF(pike_frame, locals), 1);
/* add %i2, no * sizeof(struct svalue), %i2 */
SPARC_ADD(SPARC_REG_I2, SPARC_REG_I2, no, 1);
} else {
SET_REG(SPARC_REG_I1, no);
/* lduw [ %pike_fp, %offset(pike_frame, locals) ], %i2 */
PIKE_LDPTR(SPARC_REG_I2, SPARC_REG_PIKE_FP,
OFFSETOF(pike_frame, locals), 1);
/* add %i2, %i1, %i2 */
SPARC_ADD(SPARC_REG_I2, SPARC_REG_I2, SPARC_REG_I1, 0);
}
/* stw %i2, [ %pike_sp, %offset(svalue, u.lval) ] */
PIKE_STPTR(SPARC_REG_I2, SPARC_REG_PIKE_SP,
- OFFSETOF(svalue, u.lval), 1);
- /* add %pike_sp, sizeof(struct svalue) * 2, %pike_sp */
- SPARC_ADD(SPARC_REG_PIKE_SP, SPARC_REG_PIKE_SP, sizeof(struct svalue)*2, 1);
+ sparc_pike_sp_bias + OFFSETOF(svalue, u.lval), 1);
+ sparc_pike_sp_bias += sizeof(struct svalue) * 2;
/* sth %i0, [ %pike_sp , -sizeof(struct svalue) ] */
- SPARC_STH(SPARC_REG_I0, SPARC_REG_PIKE_SP, -sizeof(struct svalue), 1);
+ SPARC_STH(SPARC_REG_I0, SPARC_REG_PIKE_SP,
+ sparc_pike_sp_bias - sizeof(struct svalue), 1);
sparc_codegen_state |= SPARC_CODEGEN_SP_NEEDS_STORE;
}
void sparc_escape_catch(void)
{
LOAD_PIKE_FP();
SPARC_FLUSH_UNSTORED();
#ifdef PIKE_BYTECODE_SPARC64
/* The asr registers are implementation specific in Sparc V7 and V8. */
/* rd %pc, %i0 */
pike.git/src/code/sparc.c:621: Inside #if defined(PIKE_DEBUG)
SET_REG(SPARC_REG_PIKE_DEBUG, ((ptrdiff_t)(&d_flag)));
SPARC_LDUW(SPARC_REG_PIKE_DEBUG, SPARC_REG_PIKE_DEBUG, SPARC_REG_G0, 0);
SPARC_SUBcc(SPARC_REG_G0, SPARC_REG_PIKE_DEBUG, SPARC_REG_G0, 0);
SET_REG(SPARC_REG_O0, state);
#ifdef PIKE_BYTECODE_SPARC64
SPARC_BE(8*4, 0);
SPARC_OR(SPARC_REG_O1, SPARC_REG_PIKE_IP, SPARC_REG_G0, 0);
SPARC_SETHI(SPARC_REG_O7, ((ptrdiff_t)sparc_debug_check_registers)>>2);
SPARC_OR(SPARC_REG_O2, SPARC_REG_PIKE_FP, SPARC_REG_G0, 0);
SPARC_SLL(SPARC_REG_O7, SPARC_REG_O7, 2, 1);
- SPARC_OR(SPARC_REG_O3, SPARC_REG_PIKE_SP, SPARC_REG_G0, 0);
+ SPARC_ADD(SPARC_REG_O3, SPARC_REG_PIKE_SP, sparc_pike_sp_bias, 1);
SPARC_JMPL(SPARC_REG_O7, SPARC_REG_O7,
((ptrdiff_t)sparc_debug_check_registers) & 0xfff, 1);
SPARC_OR(SPARC_REG_O4, SPARC_REG_PIKE_MARK_SP, SPARC_REG_G0, 0);
#else /* !PIKE_BYTECODE_SPARC64 */
/* NOTE: Assumes ADD_CALL below is a single instruction. */
SPARC_BE(6*4, 0);
SPARC_OR(SPARC_REG_O1, SPARC_REG_PIKE_IP, SPARC_REG_G0, 0);
SPARC_OR(SPARC_REG_O2, SPARC_REG_PIKE_FP, SPARC_REG_G0, 0);
- SPARC_OR(SPARC_REG_O3, SPARC_REG_PIKE_SP, SPARC_REG_G0, 0);
+ SPARC_ADD(SPARC_REG_O3, SPARC_REG_PIKE_SP, sparc_pike_sp_bias, 1);
SPARC_OR(SPARC_REG_O4, SPARC_REG_PIKE_MARK_SP, SPARC_REG_G0, 0);
ADD_CALL(sparc_debug_check_registers, 1);
#endif /* PIKE_BYTECODE_SPARC64 */
}
}
#else /* !PIKE_DEBUG */
#define ins_sparc_debug()
#endif /* PIKE_DEBUG */
static void low_ins_call(void *addr, int delay_ok, int i_flags)
pike.git/src/code/sparc.c:784:
void ins_f_byte_with_arg(unsigned int a,unsigned INT32 b)
{
ins_sparc_debug();
switch(a) {
case F_NUMBER:
sparc_push_int(b, 0);
return;
case F_NEG_NUMBER:
- sparc_push_int(-b, 0);
+ sparc_push_int(-(ptrdiff_t)b, 0);
return;
case F_LFUN:
sparc_push_lfun(b);
return;
case F_MARK_X:
- sparc_mark(-b);
+ sparc_mark(-(ptrdiff_t)b);
return;
case F_LOCAL_LVALUE:
sparc_local_lvalue(b);
return;
}
SET_REG(SPARC_REG_O0, b);
low_ins_f_byte(a, 1);
return;
}
pike.git/src/code/sparc.c:837:
#endif /* PIKE_DEBUG */
adddata2(p->program + prev, off - prev);
#ifdef PIKE_DEBUG
if ((p->program[off] & 0xc0000000) != 0x40000000) {
Pike_fatal("Bad relocation!\n");
}
#endif /* PIKE_DEBUG */
/* Relocate to being relative to NULL */
opcode = 0x40000000 |
- ((p->program[off] + (((INT32)(p->program)>>2))) & 0x3fffffff);
+ ((p->program[off] + (((INT32)(ptrdiff_t)(p->program)>>2))) & 0x3fffffff);
adddata2(&opcode, 1);
prev = off+1;
}
adddata2(p->program + prev, p->num_program - prev);
}
void sparc_decode_program(struct program *p)
{
/* Relocate the program... */
PIKE_OPCODE_T *prog = p->program;
- INT32 delta = ((INT32)p->program)>>2;
+ INT32 delta = ((INT32)(ptrdiff_t)p->program)>>2;
size_t rel = p->num_relocations;
while (rel--) {
#ifdef PIKE_DEBUG
if ((prog[p->relocations[rel]] & 0xc0000000) != 0x40000000) {
Pike_error("Bad relocation: %d, off:%d, opcode: 0x%08x\n",
rel, p->relocations[rel],
prog[p->relocations[rel]]);
}
#endif /* PIKE_DEBUG */
prog[p->relocations[rel]] = 0x40000000 |