pike.git / src / code / sparc.c

version» Context lines:

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 |