168 // narrow OOPs by setting the upper 16 bits in the first
169 // instruction.
170 if (Instruction_aarch64::extract(insn, 31, 21) == 0b11010010101) {
171 // Move narrow OOP
172 narrowOop n = oopDesc::encode_heap_oop((oop)o);
173 Instruction_aarch64::patch(insn_addr, 20, 5, n >> 16);
174 Instruction_aarch64::patch(insn_addr+4, 20, 5, n & 0xffff);
175 instructions = 2;
176 } else {
177 // Move wide OOP
178 assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
179 uintptr_t dest = (uintptr_t)o;
180 Instruction_aarch64::patch(insn_addr, 20, 5, dest & 0xffff);
181 Instruction_aarch64::patch(insn_addr+4, 20, 5, (dest >>= 16) & 0xffff);
182 Instruction_aarch64::patch(insn_addr+8, 20, 5, (dest >>= 16) & 0xffff);
183 instructions = 3;
184 }
185 return instructions * NativeInstruction::instruction_size;
186 }
187
188 address MacroAssembler::target_addr_for_insn(address insn_addr, unsigned insn) {
189 long offset = 0;
190 if ((Instruction_aarch64::extract(insn, 29, 24) & 0b011011) == 0b00011000) {
191 // Load register (literal)
192 offset = Instruction_aarch64::sextract(insn, 23, 5);
193 return address(((uint64_t)insn_addr + (offset << 2)));
194 } else if (Instruction_aarch64::extract(insn, 30, 26) == 0b00101) {
195 // Unconditional branch (immediate)
196 offset = Instruction_aarch64::sextract(insn, 25, 0);
197 } else if (Instruction_aarch64::extract(insn, 31, 25) == 0b0101010) {
198 // Conditional branch (immediate)
199 offset = Instruction_aarch64::sextract(insn, 23, 5);
200 } else if (Instruction_aarch64::extract(insn, 30, 25) == 0b011010) {
201 // Compare & branch (immediate)
202 offset = Instruction_aarch64::sextract(insn, 23, 5);
203 } else if (Instruction_aarch64::extract(insn, 30, 25) == 0b011011) {
204 // Test & branch (immediate)
205 offset = Instruction_aarch64::sextract(insn, 18, 5);
206 } else if (Instruction_aarch64::extract(insn, 28, 24) == 0b10000) {
207 // PC-rel. addressing
|
168 // narrow OOPs by setting the upper 16 bits in the first
169 // instruction.
170 if (Instruction_aarch64::extract(insn, 31, 21) == 0b11010010101) {
171 // Move narrow OOP
172 narrowOop n = oopDesc::encode_heap_oop((oop)o);
173 Instruction_aarch64::patch(insn_addr, 20, 5, n >> 16);
174 Instruction_aarch64::patch(insn_addr+4, 20, 5, n & 0xffff);
175 instructions = 2;
176 } else {
177 // Move wide OOP
178 assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
179 uintptr_t dest = (uintptr_t)o;
180 Instruction_aarch64::patch(insn_addr, 20, 5, dest & 0xffff);
181 Instruction_aarch64::patch(insn_addr+4, 20, 5, (dest >>= 16) & 0xffff);
182 Instruction_aarch64::patch(insn_addr+8, 20, 5, (dest >>= 16) & 0xffff);
183 instructions = 3;
184 }
185 return instructions * NativeInstruction::instruction_size;
186 }
187
188 int MacroAssembler::patch_narrow_klass(address insn_addr, narrowKlass n) {
189 // Metatdata pointers are either narrow (32 bits) or wide (48 bits).
190 // We encode narrow ones by setting the upper 16 bits in the first
191 // instruction.
192 NativeInstruction *insn = nativeInstruction_at(insn_addr);
193 assert(Instruction_aarch64::extract(insn->encoding(), 31, 21) == 0b11010010101 &&
194 nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
195
196 Instruction_aarch64::patch(insn_addr, 20, 5, n >> 16);
197 Instruction_aarch64::patch(insn_addr+4, 20, 5, n & 0xffff);
198 return 2 * NativeInstruction::instruction_size;
199 }
200
201 address MacroAssembler::target_addr_for_insn(address insn_addr, unsigned insn) {
202 long offset = 0;
203 if ((Instruction_aarch64::extract(insn, 29, 24) & 0b011011) == 0b00011000) {
204 // Load register (literal)
205 offset = Instruction_aarch64::sextract(insn, 23, 5);
206 return address(((uint64_t)insn_addr + (offset << 2)));
207 } else if (Instruction_aarch64::extract(insn, 30, 26) == 0b00101) {
208 // Unconditional branch (immediate)
209 offset = Instruction_aarch64::sextract(insn, 25, 0);
210 } else if (Instruction_aarch64::extract(insn, 31, 25) == 0b0101010) {
211 // Conditional branch (immediate)
212 offset = Instruction_aarch64::sextract(insn, 23, 5);
213 } else if (Instruction_aarch64::extract(insn, 30, 25) == 0b011010) {
214 // Compare & branch (immediate)
215 offset = Instruction_aarch64::sextract(insn, 23, 5);
216 } else if (Instruction_aarch64::extract(insn, 30, 25) == 0b011011) {
217 // Test & branch (immediate)
218 offset = Instruction_aarch64::sextract(insn, 18, 5);
219 } else if (Instruction_aarch64::extract(insn, 28, 24) == 0b10000) {
220 // PC-rel. addressing
|