|
|
1.1 ! root 1: /* ! 2: * Cisco router simulation platform. ! 3: * Copyright (c) 2006 Christophe Fillot ([email protected]) ! 4: * ! 5: * JIT engine for 32-bit PowerPC architecture ! 6: * Copyright (c) 2006, 2007 Zhe Fang ([email protected]) ! 7: */ ! 8: ! 9: #ifndef __MIPS64_PPC32_TRANS_H__ ! 10: #define __MIPS64_PPC32_TRANS_H__ ! 11: ! 12: #include "utils.h" ! 13: #include "cpu.h" ! 14: #include "mips64_exec.h" ! 15: #include "dynamips.h" ! 16: #include "ppc-codegen.h" ! 17: ! 18: #define JIT_SUPPORT 1 ! 19: ! 20: /* Manipulate bitmasks synchronically */ ! 21: static forced_inline void atomic_or(m_uint32_t *v,m_uint32_t m) ! 22: { ! 23: __asm__ __volatile__("lwarx r0, 0, %0 \n" ! 24: "or r0, r0, %1 \n" ! 25: "stwcx. r0, 0, %0 \n" ! 26: "bne- $-12":"+p"(v): "r"(m): "r0", "memory"); ! 27: } ! 28: ! 29: static forced_inline void atomic_and(m_uint32_t *v,m_uint32_t m) ! 30: { ! 31: __asm__ __volatile__("lwarx r0, 0, %0 \n" ! 32: "and r0, r0, %1 \n" ! 33: "stwcx. r0, 0, %0 \n" ! 34: "bne- $-12":"+p"(v): "r"(m): "r0", "memory"); ! 35: } ! 36: ! 37: /* Made from ppc_patch in ppc-codegen.h */ ! 38: #define ppc_emit_jump_code(code,target,lk) do {\ ! 39: \ ! 40: /* prefer relative branches, they are more position independent (e.g. for AOT compilation). */\ ! 41: if ((target) - (code) >= 0){ \ ! 42: if ((target) - (code) <= 33554431){ \ ! 43: ppc_emit32 ((code), (18 << 26) | ((target) - (code)) | lk); \ ! 44: break; \ ! 45: } \ ! 46: } else { \ ! 47: /* diff between 0 and -33554432 */ \ ! 48: if ((target) - (code) >= -33554432){ \ ! 49: ppc_emit32 ((code), (18 << 26) | (((target) - (code)) & ~0xfc000000) | lk); \ ! 50: break; \ ! 51: } \ ! 52: } \ ! 53: \ ! 54: if ((long)(target) >= 0){ \ ! 55: if ((long)(target) <= 33554431){ \ ! 56: ppc_emit32 ((code), (18 << 26) | (unsigned int)(target) | 2 | lk); \ ! 57: break; \ ! 58: } \ ! 59: } else { \ ! 60: if ((long)(target) >= -33554432){ \ ! 61: ppc_emit32 ((code), (18 << 26) | ((unsigned int)(target) & ~0xfc000000) | 2 | lk); \ ! 62: break; \ ! 63: } \ ! 64: } \ ! 65: \ ! 66: /* The last way... */ \ ! 67: ppc_lis ((code), ppc_r12, (unsigned int)(target) >> 16); \ ! 68: ppc_ori ((code), ppc_r12, ppc_r12, (unsigned int)(target) & 0xffff); \ ! 69: ppc_mtlr((code), ppc_r12); \ ! 70: ppc_bclrx((code), PPC_BR_ALWAYS, 0, lk); \ ! 71: } while (0) ! 72: ! 73: /* Here's a hack, see comments in mips64_set_jump for more info */ ! 74: //#define mips64_jit_tcb_set_patch ppc_patch ! 75: #define mips64_jit_tcb_set_patch(a,b) ppc_emit_jump_code(a,b,0) ! 76: #define mips64_jit_tcb_set_jump(a,b) ppc_emit_jump_code(a,b,0) ! 77: ! 78: /* MIPS instruction array */ ! 79: extern struct mips64_insn_tag mips64_insn_tags[]; ! 80: ! 81: #define PPC_STACK_DECREMENTER 114 ! 82: ! 83: /* Push epilog for a ppc instruction block */ ! 84: static forced_inline void mips64_jit_tcb_push_epilog(mips64_jit_tcb_t *b) ! 85: { ! 86: /* Restore link register */ ! 87: ppc_lwz(b->jit_ptr,ppc_r0,PPC_STACK_DECREMENTER+PPC_RET_ADDR_OFFSET,ppc_r1); ! 88: ppc_mtlr(b->jit_ptr,ppc_r0); ! 89: ppc_blr(b->jit_ptr); ! 90: } ! 91: ! 92: /* Execute JIT code */ ! 93: static forced_inline ! 94: void mips64_jit_tcb_exec(cpu_mips_t *cpu,mips64_jit_tcb_t *block) ! 95: { ! 96: register insn_tblock_fptr jit_code __asm__("r12"); ! 97: m_uint32_t offset; ! 98: ! 99: offset = (cpu->pc & MIPS_MIN_PAGE_IMASK) >> 2; ! 100: jit_code = (insn_tblock_fptr)block->jit_insn_ptr[offset]; ! 101: ! 102: if (unlikely(!jit_code)) { ! 103: mips64_exec_single_step(cpu,vmtoh32(block->mips_code[offset])); ! 104: return; ! 105: } ! 106: ! 107: /* Same as C call of jit_code(cpu_mips_t *cpu) except establish and ! 108: destroy caller's stack frame here. ! 109: r0, r3 - r10, r11, r12, ctr, xer, cr0 - cr5, cr6 - cr7 are volatile ! 110: according to the ABI. ! 111: CPU instance pointer passed through r3, also preserved onto stack. ! 112: */ ! 113: __asm__ __volatile__( ! 114: "mtlr r12 \n" ! 115: "mr r3, %1 \n" ! 116: "lis r0, hi16(jit_ret) \n" ! 117: "ori r0, r0, lo16(jit_ret)\n" ! 118: "stw r3, %2(r1) \n" ! 119: "stw r0, %3(r1) \n" ! 120: "stwu r1, %4(r1) \n" ! 121: "blr \n" ! 122: "jit_ret: \n" ! 123: "lwz r1, 0(r1) \n" ! 124: :"+r"(jit_code):"r"(cpu),"i"(PPC_STACK_PARAM_OFFSET), ! 125: "i"(PPC_RET_ADDR_OFFSET),"i"(-PPC_STACK_DECREMENTER) ! 126: :"r0","r3","r4","r5","r6","r7","r8","r9","r10", ! 127: "r11",/*"r12",*/"lr","ctr","xer","cr0","cr1","cr5", ! 128: "cr6","cr7","memory"); ! 129: } ! 130: ! 131: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.