pike.git / src / code / ppc64.c

version» Context lines:

pike.git/src/code/ppc64.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.   */      /* -  * Machine code generator for 32 bit PowerPC +  * Machine code generator for 64 bit PowerPC    *    * Marcus Comstedt 20010726    */      #include "operators.h"   #include "constants.h"   #include "object.h"   #include "builtin_functions.h"      
pike.git/src/code/ppc64.c:21:   #include <CoreServices/CoreServices.h>   #endif         #if PIKE_BYTEORDER == 1234   #define MAKE_TYPE_WORD(t,st) ((t)|((st)<<16))   #else   #define MAKE_TYPE_WORD(t,st) ((st)|((t)<<16))   #endif    + #if _CALL_ELF == 2 +    #define ADD_CALL(X) do { \    INT64 func_=(INT64)(void*)(X); \    \ -  +  SET_REG64(12, func_); \ +  /* mtlr r12 */ \ +  MTSPR(12, PPC_SPREG_LR); \ +  /* blrl */ \ +  BCLRL(20, 0); \ +  } while(0) +  + #else +  + #define ADD_CALL(X) do { \ +  INT64 func_=(INT64)(void*)(X); \ +  \    SET_REG64(11, (func_+32768)&~0xffff); \    if ((func_ &= 0xffff) > 32767) \    func_ -= 65536; \ -  /* ld r0,%lo(func)(r11) */ \ -  LD(0, 11, func_); \ -  /* ld r2,%lo(func+8)(r11) */ \ -  LD(2, 11, func_+8); \ +  /* ldu r0,%lo(func)(r11) */ \ +  LDU(0, 11, func_); \ +  /* ld r2,%8(r11) */ \ +  LD(2, 11, 8); \    /* mtlr r0 */ \    MTSPR(0, PPC_SPREG_LR); \    /* blrl */ \    BCLRL(20, 0); \    } while(0)    -  + #endif +    int ppc64_codegen_state = 0, ppc64_codegen_last_pc = 0;   static int last_prog_id=-1;      void ppc64_flush_code_generator_state()   {    if(ppc64_codegen_state & PPC_CODEGEN_SP_NEEDSSTORE) {    /* stw pike_sp,stack_pointer(pike_interpreter) */    STD(PPC_REG_PIKE_SP, PPC_REG_PIKE_INTERP,    OFFSETOF(Pike_interpreter_struct, stack_pointer));    }
pike.git/src/code/ppc64.c:143:      void ppc64_push_constant(INT32 arg)   {    INT32 offs;    struct svalue *sval = &Pike_compiler->new_program->constants[arg].sval;       /*    * Note: The constants table may contain UNDEFINED in case of being    * called through decode_value() in PORTABLE_BYTECODE mode.    */ -  if(!REFCOUNTED_TYPE(TYPEOF(*sval)) && !sval->subtype) { +  if(!REFCOUNTED_TYPE(TYPEOF(*sval)) && !SUBTYPEOF(*sval)) {    int e;    INT64 last=0;       LOAD_SP_REG();       for(e=0;e<(int)sizeof(struct svalue);e+=8)    {    if(e==0 || *(INT64 *)(((char *)sval)+e) != last)    SET_REG64(0, last = *(INT64 *)(((char *)sval)+e));    /* std r0,e(pike_sp) */
pike.git/src/code/ppc64.c:256:    if(arg) {    /* addi r5,r5,arg */    ADDI(PPC_REG_ARG3, PPC_REG_ARG3, arg);    }    FLUSH_CODE_GENERATOR_STATE();    ADD_CALL(low_object_index_no_free);    LOAD_SP_REG();    INCR_SP_REG(sizeof(struct svalue));   }    - void ppc64_push_int(INT32 x, int s) + void ppc64_push_int(INT64 x, int s)   {    LOAD_SP_REG();       SET_REG32(0, 0);    if(sizeof(struct svalue) > 16)    {    int e;    for(e=8;e<(int)sizeof(struct svalue);e+=8)    {    if( e == OFFSETOF(svalue,u.integer)) continue;    /* std r0,e(pike_sp) */    STD(0, PPC_REG_PIKE_SP, e);    }    }    STW(0, PPC_REG_PIKE_SP, 4);    if(x != 0) -  SET_REG32(0, x); +  SET_REG64(0, x);    STD(0, PPC_REG_PIKE_SP, OFFSETOF(svalue,u.integer));    if(x != MAKE_TYPE_WORD(PIKE_T_INT, s))    SET_REG32(0, MAKE_TYPE_WORD(PIKE_T_INT, s));    STW(0, PPC_REG_PIKE_SP, 0);    INCR_SP_REG(sizeof(struct svalue));   }      void ppc64_push_string(INT32 arg, int st)   {    INT32 offs;
pike.git/src/code/ppc64.c:357:    LOAD_FP_REG();    /* ld r3,catch_ctx(pike_interpreter) */    LD(PPC_REG_ARG1, PPC_REG_PIKE_INTERP,    OFFSETOF(Pike_interpreter_struct, catch_ctx));    /* ld r4,recovery.previous(r3) */    LD(PPC_REG_ARG2, PPC_REG_ARG1,    OFFSETOF(catch_context, recovery.previous));    /* std r4,recoveries(pike_interpreter) */    STD(PPC_REG_ARG2, PPC_REG_PIKE_INTERP,    OFFSETOF(Pike_interpreter_struct, recoveries)); -  /* ld r4,save_expendible(r3) */ -  LD(PPC_REG_ARG2, PPC_REG_ARG1, -  OFFSETOF(catch_context, save_expendible)); -  /* std r4,expendible(pike_fp) */ -  STD(PPC_REG_ARG2, PPC_REG_PIKE_FP, -  OFFSETOF(pike_frame, expendible)); +     /* ld r4,prev(r3) */    LD(PPC_REG_ARG2, PPC_REG_ARG1,    OFFSETOF(catch_context, prev));    /* std r4,catch_ctx(pike_interpreter) */    STD(PPC_REG_ARG2, PPC_REG_PIKE_INTERP,    OFFSETOF(Pike_interpreter_struct, catch_ctx));       FLUSH_CODE_GENERATOR_STATE();    ADD_CALL(really_free_catch_context);   }
pike.git/src/code/ppc64.c:386:    static unsigned int last_num_linenumbers=~0;    if(last_prog_id != Pike_compiler->new_program->id ||    last_num_linenumbers != Pike_compiler->new_program->num_linenumbers)    {    last_prog_id=Pike_compiler->new_program->id;    last_num_linenumbers = Pike_compiler->new_program->num_linenumbers;    UPDATE_PC();    }   }    + #ifdef OPCODE_INLINE_RETURN + void ppc64_ins_entry(void) + { +  /* stdu r1, -128(r1) */ +  STDU(1, 1, -128); +  /* mflr r0 */ +  MFSPR(0, PPC_SPREG_LR); +  /* std r0, 144(r1) */ +  STD(0, 1, 144); +  /* std r2, 120(r1) */ +  STD(2, 1, 120); + } + #endif /* OPCODE_INLINE_RETURN */ +    void ins_f_byte(unsigned int b)   {    void *addr; -  +  INT32 rel_addr;       b-=F_OFFSET;   #ifdef PIKE_DEBUG    if(b>255)    Pike_error("Instruction too big %d\n",b);   #endif    maybe_update_pc();    addr = instrs[b].address;      #ifdef PIKE_DEBUG
pike.git/src/code/ppc64.c:438:    case F_ADD - F_OFFSET:    SET_REG32(PPC_REG_ARG1, 2);    addr = (void *)f_add;    break;       case F_EXIT_CATCH - F_OFFSET:    ppc64_push_int(0, 1);    case F_ESCAPE_CATCH - F_OFFSET:    ppc64_escape_catch();    return; +  + #ifdef OPCODE_INLINE_RETURN +  case F_CATCH - F_OFFSET: +  /* Special argument for the F_CATCH instruction. */ +  addr = inter_return_opcode_F_CATCH; +  /* bl .+4 */ +  BL(4); +  /* mflr r3 */ +  MFSPR(PPC_REG_ARG1, PPC_SPREG_LR); +  rel_addr = PIKE_PC; +  /* addi r3, r3, offs */ +  ADDI(PPC_REG_ARG1, PPC_REG_ARG1, 4); +  break; + #endif    }       FLUSH_CODE_GENERATOR_STATE();    ADD_CALL(addr); -  + #ifdef OPCODE_INLINE_RETURN +  if (instrs[b].flags & I_RETURN) { +  /* cmpdi r3,-1 */ +  CMPI(1, PPC_REG_RET, -1); +  /* bne .+24 */ +  BC(4, 2, 6); +  /* ld r0, 144(r1) */ +  LD(0, 1, 144); +  /* ld r2, 120(r1) */ +  LD(2, 1, 120); +  /* addi r1, r1, 128 */ +  ADDI(1, 1, 128); +  /* mtlr r0 */ +  MTSPR(0, PPC_SPREG_LR); +  /* blr */ +  BCLR(20, 0); +  +  if ((b + F_OFFSET) == F_RETURN_IF_TRUE) { +  /* Kludge. We must check if the ret addr is +  * orig_addr + JUMP_EPILOGUE_SIZE. */ +  +  /* mflr r0 */ +  MFSPR(0, PPC_SPREG_LR); +  /* subf r0, r0, r3 */ +  SUBF(0, 0, PPC_REG_RET); +  /* cmpldi r0, JUMP_EPILOGUE_SIZE */ +  CMPLI(1, 0, JUMP_EPILOGUE_SIZE*4); +  /* beq .+12 */ +  BC(12, 2, 3); +  } +  } + #endif   #ifdef OPCODE_RETURN_JUMPADDR    if (instrs[b].flags & I_JUMP) {    /* This is the code that JUMP_EPILOGUE_SIZE compensates for. */    /* mtlr r3 */    MTSPR(PPC_REG_RET, PPC_SPREG_LR);    /* blr */    BCLR(20, 0); -  +  + #ifdef OPCODE_INLINE_RETURN +  if (b == F_CATCH - F_OFFSET) { +  Pike_compiler->new_program->program[rel_addr] += (PIKE_PC - rel_addr)*4;    }   #endif    } -  + #endif + }      void ins_f_byte_with_arg(unsigned int a, INT32 b)   {    maybe_update_pc();      #ifdef PIKE_DEBUG    if (d_flag < 3)   #endif    switch(a)    {
pike.git/src/code/ppc64.c:496:       case F_ARROW_STRING:    ppc64_push_string(b, 1);    return;       case F_NUMBER:    ppc64_push_int(b, 0);    return;       case F_NEG_NUMBER: -  ppc64_push_int(-b, 0); +  ppc64_push_int(-(INT64)b, 0);    return;       case F_CONSTANT:    ppc64_push_constant(b);    return;       /*    * And this would work nicely for all non-dynamically loaded    * functions. Unfortunately there is no way to know if it is    * dynamically loaded or not at this point...
pike.git/src/code/ppc64.c:575:    CMPLI(1, PPC_REG_RET, 0);    /* beq .+8 */    BC(12, 2, 2);    pos_ = PIKE_PC;    }    if(backward_jump) {    ADD_CALL(branch_check_threads_etc);    if(pos_)    Pike_compiler->new_program->program[pos_-1] += 4*(PIKE_PC-pos_);    } -  ret=DO_NOT_WARN( (INT32) PIKE_PC ); +  ret=(INT32) PIKE_PC;    /* b . */    B(0);    return ret;   }      INT32 ppc64_ins_f_jump_with_arg(unsigned int a, unsigned INT32 b, int backward_jump)   {    if(a == F_COND_RECUR) return -1;    SET_REG32(PPC_REG_ARG1, b);    return ppc64_ins_f_jump(a, backward_jump);
pike.git/src/code/ppc64.c:652:    __asm__("icbi 0,%0" : : "r" (a));    __asm__("dcbst 0,%0" : : "r" (a));    a += 4;    }    __asm__("sync");    __asm__("isync");   #endif /* _POWER */   }      #if 0 - #define addstr(s, l) low_my_binary_strcat((s), (l), buf) + #define addstr(s, l) buffer_memcpy(buf, (s), (l))   #define adddata2(s,l) addstr((char *)(s),(l) * sizeof((s)[0]));    - void ppc64_encode_program(struct program *p, struct dynamic_buffer_s *buf) + void ppc64_encode_program(struct program *p, struct byte_buffer *buf)   {    size_t prev = 0, rel;    /* De-relocate the program... */    for (rel = 0; rel < p->num_relocations; rel++)    {    size_t off = p->relocations[rel];    INT32 opcode;   #ifdef PIKE_DEBUG    if (off < prev) {    Pike_fatal("Relocations in bad order!\n");
pike.git/src/code/ppc64.c:893: Inside #if defined(PIKE_DEBUG)
   default: instr_name = NULL; break;    }    break;    case 2:    h = ((xo&0x1ff)^160)%28;    instr_name = ((xo&0x1ff) == opxo_31_010[h]? opname_31_010[h]:NULL);    break;    case 4:    h = (xo^98)%26;    instr_name = (xo == opxo_31_100[h]? opname_31_100[h]:NULL); -  if(instr & (1<<20)) +  if(instr & (1<<20)) {    if(xo == 144)    instr_name = "Fmtocrf";    else if(xo == 19)    instr_name = "Fmfocrf"; -  +  }    break;    case 5:    h = (xo^67)%99;    instr_name = (xo == opxo_31_101[h]? opname_31_101[h]:NULL);    break;    case 6:    h = (xo^195)%15;    instr_name = (xo == opxo_31_110[h]? opname_31_110[h]:NULL);    break;    case 7:
pike.git/src/code/ppc64.c:1063: Inside #if defined(PIKE_DEBUG)
   fprintf(stderr, "%s r%d\n", instr_name, (instr>>21)&31);    } else if((xo & 639)==597)    fprintf(stderr, "%s r%d,r%d,%d\n", instr_name,    (instr>>21)&31, (instr>>16)&31, (instr>>11)&31);    else if(xo == 370 || xo == 498 || xo == 566 || xo == 598 || xo == 854)    fprintf(stderr, "%s\n", instr_name);    else if(!(xo & 4)) {    if((xo & 479)==274)    fprintf(stderr, "%s r%d,%d\n", instr_name,    (instr>>11)&31, (instr>>21)&1); -  else (xo & 32) +  else if(xo & 32)    fprintf(stderr, "%s r%d\n", instr_name, (instr>>11)&31);    else if(xo == 595)    fprintf(stderr, "%s r%d,%d\n", instr_name,    (instr>>21)&31, (instr>>16)&15);    else    fprintf(stderr, "%s r%d,r%d\n", instr_name,    (instr>>21)&31, (instr>>11)&31);    } else if(instr_name[0]=='d' || instr_name[0]=='i') {    if(xo == 278)    fprintf(stderr, "%s r%d,r%d,%d\n", instr_name,