3265 case rc_int:
3266 if (dst_lo_rc == rc_int) { // gpr --> gpr copy
3267 if (is64) {
3268 __ mov(as_Register(Matcher::_regEncode[dst_lo]),
3269 as_Register(Matcher::_regEncode[src_lo]));
3270 } else {
3271 MacroAssembler _masm(cbuf);
3272 __ movw(as_Register(Matcher::_regEncode[dst_lo]),
3273 as_Register(Matcher::_regEncode[src_lo]));
3274 }
3275 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy
3276 if (is64) {
3277 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3278 as_Register(Matcher::_regEncode[src_lo]));
3279 } else {
3280 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3281 as_Register(Matcher::_regEncode[src_lo]));
3282 }
3283 } else { // gpr --> stack spill
3284 assert(dst_lo_rc == rc_stack, "spill to bad register class");
3285 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset);
3286 }
3287 break;
3288 case rc_float:
3289 if (dst_lo_rc == rc_int) { // fpr --> gpr copy
3290 if (is64) {
3291 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]),
3292 as_FloatRegister(Matcher::_regEncode[src_lo]));
3293 } else {
3294 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]),
3295 as_FloatRegister(Matcher::_regEncode[src_lo]));
3296 }
3297 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy
3298 if (cbuf) {
3299 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3300 as_FloatRegister(Matcher::_regEncode[src_lo]));
3301 } else {
3302 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3303 as_FloatRegister(Matcher::_regEncode[src_lo]));
3304 }
3305 } else { // fpr --> stack spill
3306 assert(dst_lo_rc == rc_stack, "spill to bad register class");
3307 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
3308 is64 ? __ D : __ S, dst_offset);
3309 }
3310 break;
3311 case rc_stack:
3312 if (dst_lo_rc == rc_int) { // stack --> gpr load
3313 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset);
3314 } else if (dst_lo_rc == rc_float) { // stack --> fpr load
3315 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3316 is64 ? __ D : __ S, src_offset);
3317 } else { // stack --> stack copy
3318 assert(dst_lo_rc == rc_stack, "spill to bad register class");
3319 __ unspill(rscratch1, is64, src_offset);
3320 __ spill(rscratch1, is64, dst_offset);
3321 }
3322 break;
3323 default:
3324 assert(false, "bad rc_class for spill");
3325 ShouldNotReachHere();
3326 }
3327 }
3328
3329 if (st) {
3330 st->print("spill ");
3331 if (src_lo_rc == rc_stack) {
3332 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo));
3333 } else {
3349
3350 }
3351
3352 #ifndef PRODUCT
3353 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
3354 if (!ra_)
3355 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
3356 else
3357 implementation(NULL, ra_, false, st);
3358 }
3359 #endif
3360
3361 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
3362 implementation(&cbuf, ra_, false, NULL);
3363 }
3364
3365 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
3366 return MachNode::size(ra_);
3367 }
3368
3369 //=============================================================================
3370
3371 #ifndef PRODUCT
3372 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
3373 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
3374 int reg = ra_->get_reg_first(this);
3375 st->print("add %s, rsp, #%d]\t# box lock",
3376 Matcher::regName[reg], offset);
3377 }
3378 #endif
3379
3380 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
3381 MacroAssembler _masm(&cbuf);
3382
3383 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
3384 int reg = ra_->get_encode(this);
3385
3386 if (Assembler::operand_valid_for_add_sub_immediate(offset)) {
3387 __ add(as_Register(reg), sp, offset);
3388 } else {
|
3265 case rc_int:
3266 if (dst_lo_rc == rc_int) { // gpr --> gpr copy
3267 if (is64) {
3268 __ mov(as_Register(Matcher::_regEncode[dst_lo]),
3269 as_Register(Matcher::_regEncode[src_lo]));
3270 } else {
3271 MacroAssembler _masm(cbuf);
3272 __ movw(as_Register(Matcher::_regEncode[dst_lo]),
3273 as_Register(Matcher::_regEncode[src_lo]));
3274 }
3275 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy
3276 if (is64) {
3277 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3278 as_Register(Matcher::_regEncode[src_lo]));
3279 } else {
3280 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3281 as_Register(Matcher::_regEncode[src_lo]));
3282 }
3283 } else { // gpr --> stack spill
3284 assert(dst_lo_rc == rc_stack, "spill to bad register class");
3285 if (_spill_type == Pair) {
3286 __ spill(as_Register(Matcher::_regEncode[src_lo]),
3287 as_Register(Matcher::_regEncode[pair_hi_reg]),
3288 is64,
3289 dst_offset);
3290 } else {
3291 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset);
3292 }
3293 }
3294 break;
3295 case rc_float:
3296 if (dst_lo_rc == rc_int) { // fpr --> gpr copy
3297 if (is64) {
3298 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]),
3299 as_FloatRegister(Matcher::_regEncode[src_lo]));
3300 } else {
3301 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]),
3302 as_FloatRegister(Matcher::_regEncode[src_lo]));
3303 }
3304 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy
3305 if (cbuf) {
3306 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3307 as_FloatRegister(Matcher::_regEncode[src_lo]));
3308 } else {
3309 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3310 as_FloatRegister(Matcher::_regEncode[src_lo]));
3311 }
3312 } else { // fpr --> stack spill
3313 assert(dst_lo_rc == rc_stack, "spill to bad register class");
3314 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
3315 is64 ? __ D : __ S, dst_offset);
3316 }
3317 break;
3318 case rc_stack:
3319 if (dst_lo_rc == rc_int) { // stack --> gpr load
3320 if (_spill_type == Pair) {
3321 assert(pair_hi_reg != OptoReg::Bad, "bad register");
3322 __ unspill(as_Register(Matcher::_regEncode[dst_lo]),
3323 as_Register(Matcher::_regEncode[pair_hi_reg]),
3324 is64,
3325 src_offset);
3326 } else {
3327 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset);
3328 }
3329 } else if (dst_lo_rc == rc_float) { // stack --> fpr load
3330 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
3331 is64 ? __ D : __ S, src_offset);
3332 } else { // stack --> stack copy
3333 assert(dst_lo_rc == rc_stack, "spill to bad register class");
3334 __ unspill(rscratch1, is64, src_offset);
3335 __ spill(rscratch1, is64, dst_offset);
3336 }
3337 break;
3338 default:
3339 assert(false, "bad rc_class for spill");
3340 ShouldNotReachHere();
3341 }
3342 }
3343
3344 if (st) {
3345 st->print("spill ");
3346 if (src_lo_rc == rc_stack) {
3347 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo));
3348 } else {
3364
3365 }
3366
3367 #ifndef PRODUCT
3368 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
3369 if (!ra_)
3370 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
3371 else
3372 implementation(NULL, ra_, false, st);
3373 }
3374 #endif
3375
3376 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
3377 implementation(&cbuf, ra_, false, NULL);
3378 }
3379
3380 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
3381 return MachNode::size(ra_);
3382 }
3383
3384 MachNode *MachSpillCopyNode::peephole(Block *block, int block_index, PhaseRegAlloc *ra_, int &deleted) {
3385 MachSpillCopyNode *inst0 = this;
3386 MachSpillCopyNode *inst1 = NULL;
3387 if ( block_index - 1 > 0 ) {
3388 Node *n = block->get_node(block_index - 1);
3389 inst1 = (n->is_MachSpillCopy()) ? n->as_MachSpillCopy() : NULL;
3390 }
3391 if (inst1 == NULL) {
3392 return NULL;
3393 }
3394 if (bottom_type()->isa_vect() != NULL ||
3395 inst1->bottom_type()->isa_vect() != NULL ||
3396 _spill_type == Pair ||
3397 inst1->_spill_type == Pair) {
3398 return NULL;
3399 }
3400 //
3401 OptoReg::Name src_lo = ra_->get_reg_first(in(1));
3402 OptoReg::Name dst_lo = ra_->get_reg_first(this);
3403 enum RC src_lo_rc = rc_class(src_lo);
3404 enum RC dst_lo_rc = rc_class(dst_lo);
3405 OptoReg::Name inst1_src_lo = ra_->get_reg_first(inst1->in(1));
3406 OptoReg::Name inst1_dst_lo = ra_->get_reg_first(inst1);
3407 enum RC inst1_src_lo_rc = rc_class(inst1_src_lo);
3408 enum RC inst1_dst_lo_rc = rc_class(inst1_dst_lo);
3409 if (((src_lo_rc == rc_stack && dst_lo_rc == rc_int)
3410 || (dst_lo_rc == rc_stack && src_lo_rc == rc_int))
3411 && ((inst1_src_lo_rc == rc_stack && inst1_dst_lo_rc == rc_int)
3412 || (inst1_dst_lo_rc == rc_stack && inst1_src_lo_rc == rc_int))) {
3413 OptoReg::Name src_hi = ra_->get_reg_second(in(1));
3414 OptoReg::Name dst_hi = ra_->get_reg_second(this);
3415 enum RC dst_hi_rc = rc_class(dst_hi);
3416 enum RC src_hi_rc = rc_class(src_hi);
3417 OptoReg::Name inst1_src_hi = ra_->get_reg_second(inst1->in(1));
3418 OptoReg::Name inst1_dst_hi = ra_->get_reg_second(inst1);
3419 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi &&
3420 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi;
3421 bool inst1_is64 = (inst1_src_lo & 1) == 0 && inst1_src_lo + 1 == inst1_src_hi &&
3422 (inst1_dst_lo & 1) == 0 && inst1_dst_lo + 1 == inst1_dst_hi;
3423 if (is64 ^ inst1_is64) {
3424 return NULL;
3425 }
3426 int offset = 0;
3427 OptoReg::Name other_reg = OptoReg::Bad;
3428 MachSpillCopyNode* pair = NULL;
3429 int src_offset = ra_->reg2offset(src_lo);
3430 int dst_offset = ra_->reg2offset(dst_lo);
3431 int inst1_src_offset = ra_->reg2offset(inst1_src_lo);
3432 int inst1_dst_offset = ra_->reg2offset(inst1_dst_lo);
3433 if (dst_lo_rc == rc_stack) {
3434 assert(dst_offset >= 0, "invalid offset");
3435 offset = dst_offset - inst1_dst_offset;
3436 } else if (src_lo_rc == rc_stack) {
3437 assert(src_offset >= 0, "invalid offset");
3438 offset = src_offset - inst1_src_offset;
3439 }
3440 // TODO alignment check for some CPU.
3441 if ((is64 && abs(offset) == 8) || (!is64 && abs(offset) == 4)) { // TODO: 8/4 magic number
3442 if (offset < 0) { // (this, inst1)
3443 pair = this;
3444 pair->pair_hi_reg = (src_lo_rc == rc_stack) ? inst1_dst_lo : inst1_src_lo;
3445 if (Verbose) {
3446 tty->print_cr("DEBUG: valid replacement found: %d && %d", pair->_idx, inst1->_idx);
3447 }
3448 } else { // (inst1, this)
3449 pair = inst1;
3450 pair->pair_hi_reg = (src_lo_rc == rc_stack) ? dst_lo : src_lo;
3451 if (Verbose) {
3452 tty->print_cr("DEBUG: valid replacement found: %d && %d", pair->_idx, this->_idx);
3453 }
3454 }
3455 pair->_spill_type = Pair;
3456 deleted = 2;
3457 return pair;
3458 }
3459 }
3460 return NULL;
3461 }
3462
3463 //=============================================================================
3464
3465 #ifndef PRODUCT
3466 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
3467 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
3468 int reg = ra_->get_reg_first(this);
3469 st->print("add %s, rsp, #%d]\t# box lock",
3470 Matcher::regName[reg], offset);
3471 }
3472 #endif
3473
3474 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
3475 MacroAssembler _masm(&cbuf);
3476
3477 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
3478 int reg = ra_->get_encode(this);
3479
3480 if (Assembler::operand_valid_for_add_sub_immediate(offset)) {
3481 __ add(as_Register(reg), sp, offset);
3482 } else {
|