6 /* Load a 32-bit value from a PowerPC LIS/ORI sequence */
7 fixnum instruction_operand::load_value_2_2()
9 cell *ptr = (cell *)pointer;
10 cell hi = (ptr[-1] & 0xffff);
11 cell lo = (ptr[ 0] & 0xffff);
15 /* Load a value from a bitfield of a PowerPC instruction */
16 fixnum instruction_operand::load_value_masked(cell mask, fixnum shift)
18 cell *ptr = (cell *)pointer;
20 return (*ptr & mask) << shift;
23 fixnum instruction_operand::load_value(cell relative_to)
27 case RC_ABSOLUTE_CELL:
28 return *(cell *)pointer;
30 return *(u32*)pointer;
32 return *(s32*)pointer + relative_to + sizeof(u32);
33 case RC_ABSOLUTE_PPC_2_2:
34 return load_value_2_2();
35 case RC_ABSOLUTE_PPC_2:
36 return load_value_masked(rel_absolute_ppc_2_mask,0);
37 case RC_RELATIVE_PPC_2:
38 return load_value_masked(rel_relative_ppc_2_mask,0) + relative_to;
39 case RC_RELATIVE_PPC_3:
40 return load_value_masked(rel_relative_ppc_3_mask,0) + relative_to;
41 case RC_RELATIVE_ARM_3:
42 return load_value_masked(rel_relative_arm_3_mask,2) + relative_to + sizeof(cell) * 2;
44 return load_value_masked(rel_indirect_arm_mask,0) + relative_to + sizeof(cell);
45 case RC_INDIRECT_ARM_PC:
46 return load_value_masked(rel_indirect_arm_mask,0) + relative_to + sizeof(cell) * 2;
48 critical_error("Bad rel class",rel_class);
53 fixnum instruction_operand::load_value()
55 return load_value(pointer);
58 code_block *instruction_operand::load_code_block()
60 return ((code_block *)load_value() - 1);
63 /* Store a 32-bit value into a PowerPC LIS/ORI sequence */
64 void instruction_operand::store_value_2_2(fixnum value)
66 cell *ptr = (cell *)pointer;
67 ptr[-1] = ((ptr[-1] & ~0xffff) | ((value >> 16) & 0xffff));
68 ptr[ 0] = ((ptr[ 0] & ~0xffff) | (value & 0xffff));
71 /* Store a value into a bitfield of a PowerPC instruction */
72 void instruction_operand::store_value_masked(fixnum value, cell mask, fixnum shift)
74 cell *ptr = (cell *)pointer;
76 /* This is unaccurate but good enough */
77 fixnum test = (fixnum)mask >> 1;
78 if(value <= -test || value >= test)
79 critical_error("Value does not fit inside relocation",0);
81 *ptr = ((*ptr & ~mask) | ((value >> shift) & mask));
84 void instruction_operand::store_value(fixnum absolute_value)
86 fixnum relative_value = absolute_value - pointer;
90 case RC_ABSOLUTE_CELL:
91 *(cell *)pointer = absolute_value;
94 *(u32*)pointer = absolute_value;
97 *(s32*)pointer = relative_value - sizeof(u32);
99 case RC_ABSOLUTE_PPC_2_2:
100 store_value_2_2(absolute_value);
102 case RC_ABSOLUTE_PPC_2:
103 store_value_masked(absolute_value,rel_absolute_ppc_2_mask,0);
105 case RC_RELATIVE_PPC_2:
106 store_value_masked(relative_value,rel_relative_ppc_2_mask,0);
108 case RC_RELATIVE_PPC_3:
109 store_value_masked(relative_value,rel_relative_ppc_3_mask,0);
111 case RC_RELATIVE_ARM_3:
112 store_value_masked(relative_value - sizeof(cell) * 2,rel_relative_arm_3_mask,2);
114 case RC_INDIRECT_ARM:
115 store_value_masked(relative_value - sizeof(cell),rel_indirect_arm_mask,0);
117 case RC_INDIRECT_ARM_PC:
118 store_value_masked(relative_value - sizeof(cell) * 2,rel_indirect_arm_mask,0);
121 critical_error("Bad rel class",rel_class);
126 void instruction_operand::store_code_block(code_block *compiled)
128 store_value((cell)compiled->xt());