Mercurial > hg > truffle
comparison src/cpu/x86/vm/interp_masm_x86_32.cpp @ 1513:df736661d0c8
Merge
author | jrose |
---|---|
date | Tue, 11 May 2010 15:19:19 -0700 |
parents | 2338d41fbd81 |
children | c18cbe5936b8 ab102d5d923e |
comparison
equal
deleted
inserted
replaced
1496:e8e83be27dd7 | 1513:df736661d0c8 |
---|---|
263 } | 263 } |
264 } | 264 } |
265 | 265 |
266 // Java Expression Stack | 266 // Java Expression Stack |
267 | 267 |
268 #ifdef ASSERT | |
269 void InterpreterMacroAssembler::verify_stack_tag(frame::Tag t) { | |
270 if (TaggedStackInterpreter) { | |
271 Label okay; | |
272 cmpptr(Address(rsp, wordSize), (int32_t)t); | |
273 jcc(Assembler::equal, okay); | |
274 // Also compare if the stack value is zero, then the tag might | |
275 // not have been set coming from deopt. | |
276 cmpptr(Address(rsp, 0), 0); | |
277 jcc(Assembler::equal, okay); | |
278 stop("Java Expression stack tag value is bad"); | |
279 bind(okay); | |
280 } | |
281 } | |
282 #endif // ASSERT | |
283 | |
284 void InterpreterMacroAssembler::pop_ptr(Register r) { | 268 void InterpreterMacroAssembler::pop_ptr(Register r) { |
285 debug_only(verify_stack_tag(frame::TagReference)); | |
286 pop(r); | 269 pop(r); |
287 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); | 270 } |
288 } | 271 |
289 | 272 void InterpreterMacroAssembler::pop_i(Register r) { |
290 void InterpreterMacroAssembler::pop_ptr(Register r, Register tag) { | |
291 pop(r); | 273 pop(r); |
292 // Tag may not be reference for jsr, can be returnAddress | |
293 if (TaggedStackInterpreter) pop(tag); | |
294 } | |
295 | |
296 void InterpreterMacroAssembler::pop_i(Register r) { | |
297 debug_only(verify_stack_tag(frame::TagValue)); | |
298 pop(r); | |
299 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); | |
300 } | 274 } |
301 | 275 |
302 void InterpreterMacroAssembler::pop_l(Register lo, Register hi) { | 276 void InterpreterMacroAssembler::pop_l(Register lo, Register hi) { |
303 debug_only(verify_stack_tag(frame::TagValue)); | |
304 pop(lo); | 277 pop(lo); |
305 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); | |
306 debug_only(verify_stack_tag(frame::TagValue)); | |
307 pop(hi); | 278 pop(hi); |
308 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); | |
309 } | 279 } |
310 | 280 |
311 void InterpreterMacroAssembler::pop_f() { | 281 void InterpreterMacroAssembler::pop_f() { |
312 debug_only(verify_stack_tag(frame::TagValue)); | |
313 fld_s(Address(rsp, 0)); | 282 fld_s(Address(rsp, 0)); |
314 addptr(rsp, 1 * wordSize); | 283 addptr(rsp, 1 * wordSize); |
315 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); | |
316 } | 284 } |
317 | 285 |
318 void InterpreterMacroAssembler::pop_d() { | 286 void InterpreterMacroAssembler::pop_d() { |
319 // Write double to stack contiguously and load into ST0 | |
320 pop_dtos_to_rsp(); | |
321 fld_d(Address(rsp, 0)); | 287 fld_d(Address(rsp, 0)); |
322 addptr(rsp, 2 * wordSize); | 288 addptr(rsp, 2 * wordSize); |
323 } | 289 } |
324 | 290 |
325 | |
326 // Pop the top of the java expression stack to execution stack (which | |
327 // happens to be the same place). | |
328 void InterpreterMacroAssembler::pop_dtos_to_rsp() { | |
329 if (TaggedStackInterpreter) { | |
330 // Pop double value into scratch registers | |
331 debug_only(verify_stack_tag(frame::TagValue)); | |
332 pop(rax); | |
333 addptr(rsp, 1* wordSize); | |
334 debug_only(verify_stack_tag(frame::TagValue)); | |
335 pop(rdx); | |
336 addptr(rsp, 1* wordSize); | |
337 push(rdx); | |
338 push(rax); | |
339 } | |
340 } | |
341 | |
342 void InterpreterMacroAssembler::pop_ftos_to_rsp() { | |
343 if (TaggedStackInterpreter) { | |
344 debug_only(verify_stack_tag(frame::TagValue)); | |
345 pop(rax); | |
346 addptr(rsp, 1 * wordSize); | |
347 push(rax); // ftos is at rsp | |
348 } | |
349 } | |
350 | 291 |
351 void InterpreterMacroAssembler::pop(TosState state) { | 292 void InterpreterMacroAssembler::pop(TosState state) { |
352 switch (state) { | 293 switch (state) { |
353 case atos: pop_ptr(rax); break; | 294 case atos: pop_ptr(rax); break; |
354 case btos: // fall through | 295 case btos: // fall through |
363 } | 304 } |
364 verify_oop(rax, state); | 305 verify_oop(rax, state); |
365 } | 306 } |
366 | 307 |
367 void InterpreterMacroAssembler::push_ptr(Register r) { | 308 void InterpreterMacroAssembler::push_ptr(Register r) { |
368 if (TaggedStackInterpreter) push(frame::TagReference); | |
369 push(r); | 309 push(r); |
370 } | 310 } |
371 | 311 |
372 void InterpreterMacroAssembler::push_ptr(Register r, Register tag) { | 312 void InterpreterMacroAssembler::push_i(Register r) { |
373 if (TaggedStackInterpreter) push(tag); // tag first | |
374 push(r); | 313 push(r); |
375 } | 314 } |
376 | 315 |
377 void InterpreterMacroAssembler::push_i(Register r) { | |
378 if (TaggedStackInterpreter) push(frame::TagValue); | |
379 push(r); | |
380 } | |
381 | |
382 void InterpreterMacroAssembler::push_l(Register lo, Register hi) { | 316 void InterpreterMacroAssembler::push_l(Register lo, Register hi) { |
383 if (TaggedStackInterpreter) push(frame::TagValue); | |
384 push(hi); | 317 push(hi); |
385 if (TaggedStackInterpreter) push(frame::TagValue); | |
386 push(lo); | 318 push(lo); |
387 } | 319 } |
388 | 320 |
389 void InterpreterMacroAssembler::push_f() { | 321 void InterpreterMacroAssembler::push_f() { |
390 if (TaggedStackInterpreter) push(frame::TagValue); | |
391 // Do not schedule for no AGI! Never write beyond rsp! | 322 // Do not schedule for no AGI! Never write beyond rsp! |
392 subptr(rsp, 1 * wordSize); | 323 subptr(rsp, 1 * wordSize); |
393 fstp_s(Address(rsp, 0)); | 324 fstp_s(Address(rsp, 0)); |
394 } | 325 } |
395 | 326 |
396 void InterpreterMacroAssembler::push_d(Register r) { | 327 void InterpreterMacroAssembler::push_d(Register r) { |
397 if (TaggedStackInterpreter) { | 328 // Do not schedule for no AGI! Never write beyond rsp! |
398 // Double values are stored as: | 329 subptr(rsp, 2 * wordSize); |
399 // tag | 330 fstp_d(Address(rsp, 0)); |
400 // high | |
401 // tag | |
402 // low | |
403 push(frame::TagValue); | |
404 subptr(rsp, 3 * wordSize); | |
405 fstp_d(Address(rsp, 0)); | |
406 // move high word up to slot n-1 | |
407 movl(r, Address(rsp, 1*wordSize)); | |
408 movl(Address(rsp, 2*wordSize), r); | |
409 // move tag | |
410 movl(Address(rsp, 1*wordSize), frame::TagValue); | |
411 } else { | |
412 // Do not schedule for no AGI! Never write beyond rsp! | |
413 subptr(rsp, 2 * wordSize); | |
414 fstp_d(Address(rsp, 0)); | |
415 } | |
416 } | 331 } |
417 | 332 |
418 | 333 |
419 void InterpreterMacroAssembler::push(TosState state) { | 334 void InterpreterMacroAssembler::push(TosState state) { |
420 verify_oop(rax, state); | 335 verify_oop(rax, state); |
431 default : ShouldNotReachHere(); | 346 default : ShouldNotReachHere(); |
432 } | 347 } |
433 } | 348 } |
434 | 349 |
435 | 350 |
436 // Tagged stack helpers for swap and dup | 351 // Helpers for swap and dup |
437 void InterpreterMacroAssembler::load_ptr_and_tag(int n, Register val, | 352 void InterpreterMacroAssembler::load_ptr(int n, Register val) { |
438 Register tag) { | |
439 movptr(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); | 353 movptr(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); |
440 if (TaggedStackInterpreter) { | 354 } |
441 movptr(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); | 355 |
442 } | 356 void InterpreterMacroAssembler::store_ptr(int n, Register val) { |
443 } | |
444 | |
445 void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, | |
446 Register tag) { | |
447 movptr(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); | 357 movptr(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); |
448 if (TaggedStackInterpreter) { | 358 } |
449 movptr(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); | |
450 } | |
451 } | |
452 | |
453 | |
454 // Tagged local support | |
455 void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { | |
456 if (TaggedStackInterpreter) { | |
457 if (tag == frame::TagCategory2) { | |
458 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)frame::TagValue); | |
459 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)frame::TagValue); | |
460 } else { | |
461 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)tag); | |
462 } | |
463 } | |
464 } | |
465 | |
466 void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { | |
467 if (TaggedStackInterpreter) { | |
468 if (tag == frame::TagCategory2) { | |
469 movptr(Address(rdi, idx, Interpreter::stackElementScale(), | |
470 Interpreter::local_tag_offset_in_bytes(1)), (int32_t)frame::TagValue); | |
471 movptr(Address(rdi, idx, Interpreter::stackElementScale(), | |
472 Interpreter::local_tag_offset_in_bytes(0)), (int32_t)frame::TagValue); | |
473 } else { | |
474 movptr(Address(rdi, idx, Interpreter::stackElementScale(), | |
475 Interpreter::local_tag_offset_in_bytes(0)), (int32_t)tag); | |
476 } | |
477 } | |
478 } | |
479 | |
480 void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { | |
481 if (TaggedStackInterpreter) { | |
482 // can only be TagValue or TagReference | |
483 movptr(Address(rdi, idx, Interpreter::stackElementScale(), | |
484 Interpreter::local_tag_offset_in_bytes(0)), tag); | |
485 } | |
486 } | |
487 | |
488 | |
489 void InterpreterMacroAssembler::tag_local(Register tag, int n) { | |
490 if (TaggedStackInterpreter) { | |
491 // can only be TagValue or TagReference | |
492 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), tag); | |
493 } | |
494 } | |
495 | |
496 #ifdef ASSERT | |
497 void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, int n) { | |
498 if (TaggedStackInterpreter) { | |
499 frame::Tag t = tag; | |
500 if (tag == frame::TagCategory2) { | |
501 Label nbl; | |
502 t = frame::TagValue; // change to what is stored in locals | |
503 cmpptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)t); | |
504 jcc(Assembler::equal, nbl); | |
505 stop("Local tag is bad for long/double"); | |
506 bind(nbl); | |
507 } | |
508 Label notBad; | |
509 cmpptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)t); | |
510 jcc(Assembler::equal, notBad); | |
511 // Also compare if the local value is zero, then the tag might | |
512 // not have been set coming from deopt. | |
513 cmpptr(Address(rdi, Interpreter::local_offset_in_bytes(n)), 0); | |
514 jcc(Assembler::equal, notBad); | |
515 stop("Local tag is bad"); | |
516 bind(notBad); | |
517 } | |
518 } | |
519 | |
520 void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, Register idx) { | |
521 if (TaggedStackInterpreter) { | |
522 frame::Tag t = tag; | |
523 if (tag == frame::TagCategory2) { | |
524 Label nbl; | |
525 t = frame::TagValue; // change to what is stored in locals | |
526 cmpptr(Address(rdi, idx, Interpreter::stackElementScale(), | |
527 Interpreter::local_tag_offset_in_bytes(1)), (int32_t)t); | |
528 jcc(Assembler::equal, nbl); | |
529 stop("Local tag is bad for long/double"); | |
530 bind(nbl); | |
531 } | |
532 Label notBad; | |
533 cmpl(Address(rdi, idx, Interpreter::stackElementScale(), | |
534 Interpreter::local_tag_offset_in_bytes(0)), (int32_t)t); | |
535 jcc(Assembler::equal, notBad); | |
536 // Also compare if the local value is zero, then the tag might | |
537 // not have been set coming from deopt. | |
538 cmpptr(Address(rdi, idx, Interpreter::stackElementScale(), | |
539 Interpreter::local_offset_in_bytes(0)), 0); | |
540 jcc(Assembler::equal, notBad); | |
541 stop("Local tag is bad"); | |
542 bind(notBad); | |
543 | |
544 } | |
545 } | |
546 #endif // ASSERT | |
547 | 359 |
548 void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point) { | 360 void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point) { |
549 MacroAssembler::call_VM_leaf_base(entry_point, 0); | 361 MacroAssembler::call_VM_leaf_base(entry_point, 0); |
550 } | 362 } |
551 | 363 |