4 #define FACTOR_CPU_STRING "ppc"
6 /* In the instruction sequence:
11 the offset from the immediate operand to LOAD32 to the instruction after
12 the branch is one instruction. */
13 static const fixnum xt_tail_pic_offset = 4;
15 inline static void check_call_site(cell return_address)
17 cell insn = *(cell *)return_address;
18 /* Check that absolute bit is 0 */
19 assert((insn & 0x2) == 0x0);
20 /* Check that instruction is branch */
21 assert((insn >> 26) == 0x12);
24 static const cell b_mask = 0x3fffffc;
26 inline static void *get_call_target(cell return_address)
28 return_address -= sizeof(cell);
29 check_call_site(return_address);
31 cell insn = *(cell *)return_address;
32 cell unsigned_addr = (insn & b_mask);
33 fixnum signed_addr = (fixnum)(unsigned_addr << 6) >> 6;
34 return (void *)(signed_addr + return_address);
37 inline static void set_call_target(cell return_address, void *target)
39 return_address -= sizeof(cell);
40 check_call_site(return_address);
42 cell insn = *(cell *)return_address;
44 fixnum relative_address = ((cell)target - return_address);
45 insn = ((insn & ~b_mask) | (relative_address & b_mask));
46 *(cell *)return_address = insn;
48 /* Flush the cache line containing the call we just patched */
49 __asm__ __volatile__ ("icbi 0, %0\n" "sync\n"::"r" (return_address):);
52 inline static bool tail_call_site_p(cell return_address)
54 return_address -= sizeof(cell);
55 cell insn = *(cell *)return_address;
56 return (insn & 0x1) == 0;
59 inline static unsigned int fpu_status(unsigned int status)
63 if (status & 0x20000000)
64 r |= FP_TRAP_INVALID_OPERATION;
65 if (status & 0x10000000)
66 r |= FP_TRAP_OVERFLOW;
67 if (status & 0x08000000)
68 r |= FP_TRAP_UNDERFLOW;
69 if (status & 0x04000000)
70 r |= FP_TRAP_ZERO_DIVIDE;
71 if (status & 0x02000000)
77 /* Defined in assembly */
78 VM_C_API void flush_icache(cell start, cell len);