|
|
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.