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 u32 *ptr = (u32 *)pointer;
13 cell hi = (ptr[-2] & 0xffff);
14 cell lo = (ptr[-1] & 0xffff);
18 /* Load a 64-bit value from a PowerPC LIS/ORI/SLDI/ORIS/ORI sequence */
19 fixnum instruction_operand::load_value_2_2_2_2()
21 u32 *ptr = (u32 *)pointer;
22 u64 hhi = (ptr[-5] & 0xffff);
23 u64 hlo = (ptr[-4] & 0xffff);
24 u64 lhi = (ptr[-2] & 0xffff);
25 u64 llo = (ptr[-1] & 0xffff);
26 u64 val = hhi << 48 | hlo << 32 | lhi << 16 | llo;
30 /* Load a value from a bitfield of a PowerPC instruction */
31 fixnum instruction_operand::load_value_masked(cell mask, cell bits, cell shift)
33 s32 *ptr = (s32 *)(pointer - sizeof(u32));
35 return (((*ptr & (s32)mask) << bits) >> bits) << shift;
38 fixnum instruction_operand::load_value(cell relative_to)
40 switch(rel.rel_class())
42 case RC_ABSOLUTE_CELL:
43 return *(cell *)(pointer - sizeof(cell));
45 return *(u32 *)(pointer - sizeof(u32));
47 return *(s32 *)(pointer - sizeof(u32)) + relative_to;
48 case RC_ABSOLUTE_PPC_2_2:
49 return load_value_2_2();
50 case RC_ABSOLUTE_PPC_2:
51 return load_value_masked(rel_absolute_ppc_2_mask,16,0);
52 case RC_RELATIVE_PPC_2_PC:
53 return load_value_masked(rel_relative_ppc_2_mask,16,0) + relative_to - 4;
54 case RC_RELATIVE_PPC_3_PC:
55 return load_value_masked(rel_relative_ppc_3_mask,6,0) + relative_to - 4;
56 case RC_RELATIVE_ARM_3:
57 return load_value_masked(rel_relative_arm_3_mask,6,2) + relative_to + sizeof(cell);
59 return load_value_masked(rel_indirect_arm_mask,20,0) + relative_to;
60 case RC_INDIRECT_ARM_PC:
61 return load_value_masked(rel_indirect_arm_mask,20,0) + relative_to + sizeof(cell);
63 return *(u16 *)(pointer - sizeof(u16));
65 return *(u8 *)(pointer - sizeof(u8));
66 case RC_ABSOLUTE_PPC_2_2_2_2:
67 return load_value_2_2_2_2();
69 critical_error("Bad rel class",rel.rel_class());
74 fixnum instruction_operand::load_value()
76 return load_value(pointer);
79 code_block *instruction_operand::load_code_block(cell relative_to)
81 return ((code_block *)load_value(relative_to) - 1);
84 code_block *instruction_operand::load_code_block()
86 return load_code_block(pointer);
89 /* Store a 32-bit value into a PowerPC LIS/ORI sequence */
90 void instruction_operand::store_value_2_2(fixnum value)
92 u32 *ptr = (u32 *)pointer;
93 ptr[-2] = ((ptr[-2] & ~0xffff) | ((value >> 16) & 0xffff));
94 ptr[-1] = ((ptr[-1] & ~0xffff) | (value & 0xffff));
97 /* Store a 64-bit value into a PowerPC LIS/ORI/SLDI/ORIS/ORI sequence */
98 void instruction_operand::store_value_2_2_2_2(fixnum value)
101 u32 *ptr = (u32 *)pointer;
102 ptr[-5] = ((ptr[-5] & ~0xffff) | ((val >> 48) & 0xffff));
103 ptr[-4] = ((ptr[-4] & ~0xffff) | ((val >> 32) & 0xffff));
104 ptr[-2] = ((ptr[-2] & ~0xffff) | ((val >> 16) & 0xffff));
105 ptr[-1] = ((ptr[-1] & ~0xffff) | ((val >> 0) & 0xffff));
108 /* Store a value into a bitfield of a PowerPC instruction */
109 void instruction_operand::store_value_masked(fixnum value, cell mask, cell shift)
111 u32 *ptr = (u32 *)(pointer - sizeof(u32));
112 *ptr = (u32)((*ptr & ~mask) | ((value >> shift) & mask));
115 void instruction_operand::store_value(fixnum absolute_value)
117 fixnum relative_value = absolute_value - pointer;
119 switch(rel.rel_class())
121 case RC_ABSOLUTE_CELL:
122 *(cell *)(pointer - sizeof(cell)) = absolute_value;
125 *(u32 *)(pointer - sizeof(u32)) = (u32)absolute_value;
128 *(s32 *)(pointer - sizeof(s32)) = (s32)relative_value;
130 case RC_ABSOLUTE_PPC_2_2:
131 store_value_2_2(absolute_value);
133 case RC_ABSOLUTE_PPC_2:
134 store_value_masked(absolute_value,rel_absolute_ppc_2_mask,0);
136 case RC_RELATIVE_PPC_2_PC:
137 store_value_masked(relative_value + 4,rel_relative_ppc_2_mask,0);
139 case RC_RELATIVE_PPC_3_PC:
140 store_value_masked(relative_value + 4,rel_relative_ppc_3_mask,0);
142 case RC_RELATIVE_ARM_3:
143 store_value_masked(relative_value - sizeof(cell),rel_relative_arm_3_mask,2);
145 case RC_INDIRECT_ARM:
146 store_value_masked(relative_value,rel_indirect_arm_mask,0);
148 case RC_INDIRECT_ARM_PC:
149 store_value_masked(relative_value - sizeof(cell),rel_indirect_arm_mask,0);
152 *(u16 *)(pointer - sizeof(u16)) = (u16)absolute_value;
155 *(u8 *)(pointer - sizeof(u8)) = (u8)absolute_value;
157 case RC_ABSOLUTE_PPC_2_2_2_2:
158 store_value_2_2_2_2(absolute_value);
161 critical_error("Bad rel class",rel.rel_class());
166 void instruction_operand::store_code_block(code_block *compiled)
168 store_value((cell)compiled->entry_point());