6 instruction_operand::instruction_operand(relocation_entry rel_, code_block *compiled_, cell index_) :
7 rel(rel_), compiled(compiled_), index(index_), pointer((cell)compiled_->entry_point() + rel_.rel_offset()) {}
9 /* Load a 32-bit value from a PowerPC LIS/ORI sequence */
10 fixnum instruction_operand::load_value_2_2()
12 cell *ptr = (cell *)pointer;
13 cell hi = (ptr[-2] & 0xffff);
14 cell lo = (ptr[-1] & 0xffff);
18 /* Load a value from a bitfield of a PowerPC instruction */
19 fixnum instruction_operand::load_value_masked(cell mask, cell bits, cell shift)
21 s32 *ptr = (s32 *)(pointer - sizeof(u32));
23 return (((*ptr & (s32)mask) << bits) >> bits) << shift;
26 fixnum instruction_operand::load_value(cell relative_to)
28 switch(rel.rel_class())
30 case RC_ABSOLUTE_CELL:
31 return *(cell *)(pointer - sizeof(cell));
33 return *(u32 *)(pointer - sizeof(u32));
35 return *(s32 *)(pointer - sizeof(u32)) + relative_to;
36 case RC_ABSOLUTE_PPC_2_2:
37 return load_value_2_2();
38 case RC_ABSOLUTE_PPC_2:
39 return load_value_masked(rel_absolute_ppc_2_mask,16,0);
40 case RC_RELATIVE_PPC_2:
41 return load_value_masked(rel_relative_ppc_2_mask,16,0) + relative_to - sizeof(cell);
42 case RC_RELATIVE_PPC_3:
43 return load_value_masked(rel_relative_ppc_3_mask,6,0) + relative_to - sizeof(cell);
44 case RC_RELATIVE_ARM_3:
45 return load_value_masked(rel_relative_arm_3_mask,6,2) + relative_to + sizeof(cell);
47 return load_value_masked(rel_indirect_arm_mask,20,0) + relative_to;
48 case RC_INDIRECT_ARM_PC:
49 return load_value_masked(rel_indirect_arm_mask,20,0) + relative_to + sizeof(cell);
51 return *(u16 *)(pointer - sizeof(u16));
53 return *(u8 *)(pointer - sizeof(u8));
55 critical_error("Bad rel class",rel.rel_class());
60 fixnum instruction_operand::load_value()
62 return load_value(pointer);
65 cell instruction_operand::load_float()
67 return (cell)load_value() - boxed_float_offset;
70 cell instruction_operand::load_float(cell pointer)
72 return (cell)load_value(pointer) - boxed_float_offset;
75 cell instruction_operand::load_byte_array()
77 return (cell)load_value() - byte_array_offset;
80 cell instruction_operand::load_byte_array(cell pointer)
82 return (cell)load_value(pointer) - byte_array_offset;
85 code_block *instruction_operand::load_code_block(cell relative_to)
87 return ((code_block *)load_value(relative_to) - 1);
90 code_block *instruction_operand::load_code_block()
92 return load_code_block(pointer);
95 /* Store a 32-bit value into a PowerPC LIS/ORI sequence */
96 void instruction_operand::store_value_2_2(fixnum value)
98 cell *ptr = (cell *)pointer;
99 ptr[-2] = ((ptr[-2] & ~0xffff) | ((value >> 16) & 0xffff));
100 ptr[-1] = ((ptr[-1] & ~0xffff) | (value & 0xffff));
103 /* Store a value into a bitfield of a PowerPC instruction */
104 void instruction_operand::store_value_masked(fixnum value, cell mask, cell shift)
106 u32 *ptr = (u32 *)(pointer - sizeof(u32));
107 *ptr = (u32)((*ptr & ~mask) | ((value >> shift) & mask));
110 void instruction_operand::store_value(fixnum absolute_value)
112 fixnum relative_value = absolute_value - pointer;
114 switch(rel.rel_class())
116 case RC_ABSOLUTE_CELL:
117 *(cell *)(pointer - sizeof(cell)) = absolute_value;
120 *(u32 *)(pointer - sizeof(u32)) = (u32)absolute_value;
123 *(s32 *)(pointer - sizeof(s32)) = (s32)relative_value;
125 case RC_ABSOLUTE_PPC_2_2:
126 store_value_2_2(absolute_value);
128 case RC_ABSOLUTE_PPC_2:
129 store_value_masked(absolute_value,rel_absolute_ppc_2_mask,0);
131 case RC_RELATIVE_PPC_2:
132 store_value_masked(relative_value + sizeof(cell),rel_relative_ppc_2_mask,0);
134 case RC_RELATIVE_PPC_3:
135 store_value_masked(relative_value + sizeof(cell),rel_relative_ppc_3_mask,0);
137 case RC_RELATIVE_ARM_3:
138 store_value_masked(relative_value - sizeof(cell),rel_relative_arm_3_mask,2);
140 case RC_INDIRECT_ARM:
141 store_value_masked(relative_value,rel_indirect_arm_mask,0);
143 case RC_INDIRECT_ARM_PC:
144 store_value_masked(relative_value - sizeof(cell),rel_indirect_arm_mask,0);
147 *(u16 *)(pointer - sizeof(u16)) = (u16)absolute_value;
150 *(u8 *)(pointer - sizeof(u8)) = (u8)absolute_value;
153 critical_error("Bad rel class",rel.rel_class());
158 void instruction_operand::store_float(cell value)
160 store_value((fixnum)value + boxed_float_offset);
163 void instruction_operand::store_byte_array(cell value)
165 store_value((fixnum)value + byte_array_offset);
168 void instruction_operand::store_code_block(code_block *compiled)
170 store_value((cell)compiled->entry_point());