4245 movl(dst, src);
4246 bind(L);
4247 }
4248 }
4249
4250 void MacroAssembler::cmov32(Condition cc, Register dst, Register src) {
4251 if (VM_Version::supports_cmov()) {
4252 cmovl(cc, dst, src);
4253 } else {
4254 Label L;
4255 jccb(negate_condition(cc), L);
4256 movl(dst, src);
4257 bind(L);
4258 }
4259 }
4260
4261 void MacroAssembler::verify_oop(Register reg, const char* s) {
4262 if (!VerifyOops) return;
4263
4264 // Pass register number to verify_oop_subroutine
4265 char* b = new char[strlen(s) + 50];
4266 sprintf(b, "verify_oop: %s: %s", reg->name(), s);
4267 BLOCK_COMMENT("verify_oop {");
4268 #ifdef _LP64
4269 push(rscratch1); // save r10, trashed by movptr()
4270 #endif
4271 push(rax); // save rax,
4272 push(reg); // pass register argument
4273 ExternalAddress buffer((address) b);
4274 // avoid using pushptr, as it modifies scratch registers
4275 // and our contract is not to modify anything
4276 movptr(rax, buffer.addr());
4277 push(rax);
4278 // call indirectly to solve generation ordering problem
4279 movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
4280 call(rax);
4281 // Caller pops the arguments (oop, message) and restores rax, r10
4282 BLOCK_COMMENT("} verify_oop");
4283 }
4284
4285
4286 RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr,
4287 Register tmp,
4288 int offset) {
4289 intptr_t value = *delayed_value_addr;
4290 if (value != 0)
4291 return RegisterOrConstant(value + offset);
4292
4293 // load indirectly to solve generation ordering problem
4294 movptr(tmp, ExternalAddress((address) delayed_value_addr));
4295
4296 #ifdef ASSERT
4297 { Label L;
4298 testptr(tmp, tmp);
4299 if (WizardMode) {
4300 jcc(Assembler::notZero, L);
4301 char* buf = new char[40];
4302 sprintf(buf, "DelayedValue="INTPTR_FORMAT, delayed_value_addr[1]);
4303 STOP(buf);
4304 } else {
4305 jccb(Assembler::notZero, L);
4306 hlt();
4307 }
4308 bind(L);
4309 }
4310 #endif
4311
4312 if (offset != 0)
4313 addptr(tmp, offset);
4314
4315 return RegisterOrConstant(tmp);
4316 }
4317
4318
4319 Address MacroAssembler::argument_address(RegisterOrConstant arg_slot,
4320 int extra_slot_offset) {
4321 // cf. TemplateTable::prepare_invoke(), if (load_receiver).
4322 int stackElementSize = Interpreter::stackElementSize;
4326 assert(offset1 - offset == stackElementSize, "correct arithmetic");
4327 #endif
4328 Register scale_reg = noreg;
4329 Address::ScaleFactor scale_factor = Address::no_scale;
4330 if (arg_slot.is_constant()) {
4331 offset += arg_slot.as_constant() * stackElementSize;
4332 } else {
4333 scale_reg = arg_slot.as_register();
4334 scale_factor = Address::times(stackElementSize);
4335 }
4336 offset += wordSize; // return PC is on stack
4337 return Address(rsp, scale_reg, scale_factor, offset);
4338 }
4339
4340
4341 void MacroAssembler::verify_oop_addr(Address addr, const char* s) {
4342 if (!VerifyOops) return;
4343
4344 // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord);
4345 // Pass register number to verify_oop_subroutine
4346 char* b = new char[strlen(s) + 50];
4347 sprintf(b, "verify_oop_addr: %s", s);
4348
4349 #ifdef _LP64
4350 push(rscratch1); // save r10, trashed by movptr()
4351 #endif
4352 push(rax); // save rax,
4353 // addr may contain rsp so we will have to adjust it based on the push
4354 // we just did (and on 64 bit we do two pushes)
4355 // NOTE: 64bit seemed to have had a bug in that it did movq(addr, rax); which
4356 // stores rax into addr which is backwards of what was intended.
4357 if (addr.uses(rsp)) {
4358 lea(rax, addr);
4359 pushptr(Address(rax, LP64_ONLY(2 *) BytesPerWord));
4360 } else {
4361 pushptr(addr);
4362 }
4363
4364 ExternalAddress buffer((address) b);
4365 // pass msg argument
4366 // avoid using pushptr, as it modifies scratch registers
4367 // and our contract is not to modify anything
4368 movptr(rax, buffer.addr());
|
4245 movl(dst, src);
4246 bind(L);
4247 }
4248 }
4249
4250 void MacroAssembler::cmov32(Condition cc, Register dst, Register src) {
4251 if (VM_Version::supports_cmov()) {
4252 cmovl(cc, dst, src);
4253 } else {
4254 Label L;
4255 jccb(negate_condition(cc), L);
4256 movl(dst, src);
4257 bind(L);
4258 }
4259 }
4260
4261 void MacroAssembler::verify_oop(Register reg, const char* s) {
4262 if (!VerifyOops) return;
4263
4264 // Pass register number to verify_oop_subroutine
4265 const char* b = NULL;
4266 {
4267 ResourceMark rm;
4268 stringStream ss;
4269 ss.print("verify_oop: %s: %s", reg->name(), s);
4270 b = code_string(ss.as_string());
4271 }
4272 BLOCK_COMMENT("verify_oop {");
4273 #ifdef _LP64
4274 push(rscratch1); // save r10, trashed by movptr()
4275 #endif
4276 push(rax); // save rax,
4277 push(reg); // pass register argument
4278 ExternalAddress buffer((address) b);
4279 // avoid using pushptr, as it modifies scratch registers
4280 // and our contract is not to modify anything
4281 movptr(rax, buffer.addr());
4282 push(rax);
4283 // call indirectly to solve generation ordering problem
4284 movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
4285 call(rax);
4286 // Caller pops the arguments (oop, message) and restores rax, r10
4287 BLOCK_COMMENT("} verify_oop");
4288 }
4289
4290
4291 RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr,
4292 Register tmp,
4293 int offset) {
4294 intptr_t value = *delayed_value_addr;
4295 if (value != 0)
4296 return RegisterOrConstant(value + offset);
4297
4298 // load indirectly to solve generation ordering problem
4299 movptr(tmp, ExternalAddress((address) delayed_value_addr));
4300
4301 #ifdef ASSERT
4302 { Label L;
4303 testptr(tmp, tmp);
4304 if (WizardMode) {
4305 const char* buf = NULL;
4306 {
4307 ResourceMark rm;
4308 stringStream ss;
4309 ss.print("DelayedValue="INTPTR_FORMAT, delayed_value_addr[1]);
4310 buf = code_string(ss.as_string());
4311 }
4312 jcc(Assembler::notZero, L);
4313 STOP(buf);
4314 } else {
4315 jccb(Assembler::notZero, L);
4316 hlt();
4317 }
4318 bind(L);
4319 }
4320 #endif
4321
4322 if (offset != 0)
4323 addptr(tmp, offset);
4324
4325 return RegisterOrConstant(tmp);
4326 }
4327
4328
4329 Address MacroAssembler::argument_address(RegisterOrConstant arg_slot,
4330 int extra_slot_offset) {
4331 // cf. TemplateTable::prepare_invoke(), if (load_receiver).
4332 int stackElementSize = Interpreter::stackElementSize;
4336 assert(offset1 - offset == stackElementSize, "correct arithmetic");
4337 #endif
4338 Register scale_reg = noreg;
4339 Address::ScaleFactor scale_factor = Address::no_scale;
4340 if (arg_slot.is_constant()) {
4341 offset += arg_slot.as_constant() * stackElementSize;
4342 } else {
4343 scale_reg = arg_slot.as_register();
4344 scale_factor = Address::times(stackElementSize);
4345 }
4346 offset += wordSize; // return PC is on stack
4347 return Address(rsp, scale_reg, scale_factor, offset);
4348 }
4349
4350
4351 void MacroAssembler::verify_oop_addr(Address addr, const char* s) {
4352 if (!VerifyOops) return;
4353
4354 // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord);
4355 // Pass register number to verify_oop_subroutine
4356 const char* b = NULL;
4357 {
4358 ResourceMark rm;
4359 stringStream ss;
4360 ss.print("verify_oop_addr: %s", s);
4361 b = code_string(ss.as_string());
4362 }
4363 #ifdef _LP64
4364 push(rscratch1); // save r10, trashed by movptr()
4365 #endif
4366 push(rax); // save rax,
4367 // addr may contain rsp so we will have to adjust it based on the push
4368 // we just did (and on 64 bit we do two pushes)
4369 // NOTE: 64bit seemed to have had a bug in that it did movq(addr, rax); which
4370 // stores rax into addr which is backwards of what was intended.
4371 if (addr.uses(rsp)) {
4372 lea(rax, addr);
4373 pushptr(Address(rax, LP64_ONLY(2 *) BytesPerWord));
4374 } else {
4375 pushptr(addr);
4376 }
4377
4378 ExternalAddress buffer((address) b);
4379 // pass msg argument
4380 // avoid using pushptr, as it modifies scratch registers
4381 // and our contract is not to modify anything
4382 movptr(rax, buffer.addr());
|