5 instruction_operand::instruction_operand(relocation_entry rel,
6 code_block* compiled, cell index)
10 pointer(compiled->entry_point() + rel.offset()) {}
12 // Load a 32-bit value from a PowerPC LIS/ORI sequence
13 fixnum instruction_operand::load_value_2_2() {
14 uint32_t* ptr = (uint32_t*)pointer;
15 cell hi = (ptr[-2] & 0xffff);
16 cell lo = (ptr[-1] & 0xffff);
20 // Load a 64-bit value from a PowerPC LIS/ORI/SLDI/ORIS/ORI sequence
21 fixnum instruction_operand::load_value_2_2_2_2() {
22 uint32_t* ptr = (uint32_t*)pointer;
23 uint64_t hhi = (ptr[-5] & 0xffff);
24 uint64_t hlo = (ptr[-4] & 0xffff);
25 uint64_t lhi = (ptr[-2] & 0xffff);
26 uint64_t llo = (ptr[-1] & 0xffff);
27 uint64_t val = hhi << 48 | hlo << 32 | lhi << 16 | llo;
31 // Load a value from a bitfield of a PowerPC instruction
32 fixnum instruction_operand::load_value_masked(cell mask, cell preshift,
33 cell bits, cell postshift) {
34 int32_t* ptr = (int32_t*)(pointer - sizeof(uint32_t));
36 return ((((*ptr & (int32_t)mask) >> preshift ) << bits) >> bits) << postshift;
39 fixnum instruction_operand::load_value(cell relative_to) {
40 switch (rel.klass()) {
41 case RC_ABSOLUTE_CELL:
42 return *(cell*)(pointer - sizeof(cell));
44 return *(uint32_t*)(pointer - sizeof(uint32_t));
46 return *(int32_t*)(pointer - sizeof(uint32_t)) + relative_to;
47 case RC_ABSOLUTE_PPC_2_2:
48 return load_value_2_2();
49 case RC_ABSOLUTE_PPC_2:
50 return load_value_masked(rel_absolute_ppc_2_mask, 0, 16, 0);
51 case RC_RELATIVE_PPC_2_PC:
52 return load_value_masked(rel_relative_ppc_2_mask, 0, 16, 0) +
54 case RC_RELATIVE_PPC_3_PC:
55 return load_value_masked(rel_relative_ppc_3_mask, 0, 6, 0) +
57 case RC_RELATIVE_ARM_3:
58 return load_value_masked(rel_relative_arm_3_mask, 0, 6, 2) + relative_to +
61 return load_value_masked(rel_indirect_arm_mask, 0, 20, 0) + relative_to;
62 case RC_INDIRECT_ARM_PC:
63 return load_value_masked(rel_indirect_arm_mask, 0, 20, 0) + relative_to +
66 return *(uint16_t*)(pointer - sizeof(uint16_t));
68 return *(uint8_t*)(pointer - sizeof(uint8_t));
69 case RC_ABSOLUTE_PPC_2_2_2_2:
70 return load_value_2_2_2_2();
71 case RC_RELATIVE_ARM64_BRANCH:
72 return load_value_masked(rel_relative_arm64_branch_mask, 0, 4, 2) +
74 case RC_RELATIVE_ARM64_BCOND:
75 return load_value_masked(rel_relative_arm64_bcond_mask, 3, 11, 0) +
78 critical_error("Bad rel class", rel.klass());
83 code_block* instruction_operand::load_code_block() {
84 return ((code_block*)load_value(pointer) - 1);
87 // Store a 32-bit value into a PowerPC LIS/ORI sequence
88 void instruction_operand::store_value_2_2(fixnum value) {
89 uint32_t* ptr = (uint32_t*)pointer;
90 ptr[-2] = ((ptr[-2] & ~0xffff) | ((value >> 16) & 0xffff));
91 ptr[-1] = ((ptr[-1] & ~0xffff) | (value & 0xffff));
94 // Store a 64-bit value into a PowerPC LIS/ORI/SLDI/ORIS/ORI sequence
95 void instruction_operand::store_value_2_2_2_2(fixnum value) {
97 uint32_t* ptr = (uint32_t*)pointer;
98 ptr[-5] = ((ptr[-5] & ~0xffff) | ((val >> 48) & 0xffff));
99 ptr[-4] = ((ptr[-4] & ~0xffff) | ((val >> 32) & 0xffff));
100 ptr[-2] = ((ptr[-2] & ~0xffff) | ((val >> 16) & 0xffff));
101 ptr[-1] = ((ptr[-1] & ~0xffff) | ((val >> 0) & 0xffff));
104 // Store a value into a bitfield of a PowerPC instruction
105 void instruction_operand::store_value_masked(fixnum value, cell mask,
106 cell shift1, cell shift2) {
107 uint32_t* ptr = (uint32_t*)(pointer - sizeof(uint32_t));
108 *ptr = (uint32_t)((*ptr & ~mask) | ((value >> shift1 << shift2) & mask));
111 void instruction_operand::store_value(fixnum absolute_value) {
112 fixnum relative_value = absolute_value - pointer;
114 switch (rel.klass()) {
115 case RC_ABSOLUTE_CELL:
116 *(cell*)(pointer - sizeof(cell)) = absolute_value;
119 *(uint32_t*)(pointer - sizeof(uint32_t)) = (uint32_t)absolute_value;
122 *(int32_t*)(pointer - sizeof(int32_t)) = (int32_t)relative_value;
124 case RC_ABSOLUTE_PPC_2_2:
125 store_value_2_2(absolute_value);
127 case RC_ABSOLUTE_PPC_2:
128 store_value_masked(absolute_value, rel_absolute_ppc_2_mask, 0, 0);
130 case RC_RELATIVE_PPC_2_PC:
131 store_value_masked(relative_value + 4, rel_relative_ppc_2_mask, 0, 0);
133 case RC_RELATIVE_PPC_3_PC:
134 store_value_masked(relative_value + 4, rel_relative_ppc_3_mask, 0, 0);
136 case RC_RELATIVE_ARM_3:
137 store_value_masked(relative_value - sizeof(cell), rel_relative_arm_3_mask,
140 case RC_INDIRECT_ARM:
141 store_value_masked(relative_value, rel_indirect_arm_mask, 0, 0);
143 case RC_INDIRECT_ARM_PC:
144 store_value_masked(relative_value - sizeof(cell), rel_indirect_arm_mask,
148 *(uint16_t*)(pointer - sizeof(uint16_t)) = (uint16_t)absolute_value;
151 *(uint8_t*)(pointer - sizeof(uint8_t)) = (uint8_t)absolute_value;
153 case RC_ABSOLUTE_PPC_2_2_2_2:
154 store_value_2_2_2_2(absolute_value);
156 case RC_RELATIVE_ARM64_BRANCH:
157 store_value_masked(relative_value, rel_relative_arm64_branch_mask, 2, 0);
159 case RC_RELATIVE_ARM64_BCOND:
160 store_value_masked(relative_value, rel_relative_arm64_bcond_mask, 2, 5);
163 critical_error("Bad rel class", rel.klass());