diff options
Diffstat (limited to 'deps/v8/src/compiler/s390/code-generator-s390.cc')
-rw-r--r-- | deps/v8/src/compiler/s390/code-generator-s390.cc | 617 |
1 files changed, 615 insertions, 2 deletions
diff --git a/deps/v8/src/compiler/s390/code-generator-s390.cc b/deps/v8/src/compiler/s390/code-generator-s390.cc index ab9bd16e81..03a6430ef2 100644 --- a/deps/v8/src/compiler/s390/code-generator-s390.cc +++ b/deps/v8/src/compiler/s390/code-generator-s390.cc @@ -67,6 +67,10 @@ class S390OperandConverter final : public InstructionOperandConverter { return Operand(constant.ToInt64()); #endif case Constant::kExternalReference: + return Operand(constant.ToExternalReference()); + case Constant::kDelayedStringConstant: + return Operand::EmbeddedStringConstant( + constant.ToDelayedStringConstant()); case Constant::kHeapObject: case Constant::kRpoNumber: break; @@ -1032,6 +1036,17 @@ static inline int AssembleUnaryOp(Instruction* instr, _R _r, _M _m, _I _i) { __ LoadlW(result, result); \ } while (false) +#define ASSEMBLE_ATOMIC_BINOP_WORD64(load_and_op) \ + do { \ + Register value = i.InputRegister(2); \ + Register result = i.OutputRegister(0); \ + Register addr = r1; \ + AddressingMode mode = kMode_None; \ + MemOperand op = i.MemoryOperand(&mode); \ + __ lay(addr, op); \ + __ load_and_op(result, value, MemOperand(addr)); \ + } while (false) + #define ATOMIC_BIN_OP(bin_inst, offset, shift_amount, start, end) \ do { \ Label do_cs; \ @@ -1047,6 +1062,22 @@ static inline int AssembleUnaryOp(Instruction* instr, _R _r, _M _m, _I _i) { __ bne(&do_cs, Label::kNear); \ } while (false) +#define ATOMIC64_BIN_OP(bin_inst, offset, shift_amount, start, end) \ + do { \ + Label do_cs; \ + __ lg(prev, MemOperand(addr, offset)); \ + __ bind(&do_cs); \ + __ RotateInsertSelectBits(temp, value, Operand(start), Operand(end), \ + Operand(static_cast<intptr_t>(shift_amount)), \ + true); \ + __ bin_inst(new_val, prev, temp); \ + __ lgr(temp, prev); \ + __ RotateInsertSelectBits(temp, new_val, Operand(start), Operand(end), \ + Operand::Zero(), false); \ + __ CmpAndSwap64(prev, temp, MemOperand(addr, offset)); \ + __ bne(&do_cs, Label::kNear); \ + } while (false) + #ifdef V8_TARGET_BIG_ENDIAN #define ATOMIC_BIN_OP_HALFWORD(bin_inst, index, extract_result) \ { \ @@ -1066,6 +1097,15 @@ static inline int AssembleUnaryOp(Instruction* instr, _R _r, _M _m, _I _i) { ATOMIC_BIN_OP(bin_inst, offset, shift_amount, start, end); \ extract_result(); \ } +#define ATOMIC_BIN_OP_WORD(bin_inst, index, extract_result) \ + { \ + constexpr int offset = -(4 * index); \ + constexpr int shift_amount = 32 - (index * 32); \ + constexpr int start = 32 - shift_amount; \ + constexpr int end = start + 31; \ + ATOMIC64_BIN_OP(bin_inst, offset, shift_amount, start, end); \ + extract_result(); \ + } #else #define ATOMIC_BIN_OP_HALFWORD(bin_inst, index, extract_result) \ { \ @@ -1085,6 +1125,15 @@ static inline int AssembleUnaryOp(Instruction* instr, _R _r, _M _m, _I _i) { ATOMIC_BIN_OP(bin_inst, offset, shift_amount, start, end); \ extract_result(); \ } +#define ATOMIC_BIN_OP_WORD(bin_inst, index, extract_result) \ + { \ + constexpr int offset = -(4 * index); \ + constexpr int shift_amount = index * 32; \ + constexpr int start = 32 - shift_amount; \ + constexpr int end = start + 31; \ + ATOMIC64_BIN_OP(bin_inst, offset, shift_amount, start, end); \ + extract_result(); \ + } #endif // V8_TARGET_BIG_ENDIAN #define ASSEMBLE_ATOMIC_BINOP_HALFWORD(bin_inst, extract_result) \ @@ -1143,6 +1192,311 @@ static inline int AssembleUnaryOp(Instruction* instr, _R _r, _M _m, _I _i) { __ bind(&done); \ } while (false) +#define ASSEMBLE_ATOMIC64_BINOP_BYTE(bin_inst, extract_result) \ + do { \ + Register value = i.InputRegister(2); \ + Register result = i.OutputRegister(0); \ + Register addr = i.TempRegister(0); \ + Register prev = r0; \ + Register new_val = r1; \ + Register temp = kScratchReg; \ + AddressingMode mode = kMode_None; \ + MemOperand op = i.MemoryOperand(&mode); \ + Label done, leftmost0, leftmost1, two, three, four, five, seven; \ + __ lay(addr, op); \ + __ tmll(addr, Operand(7)); \ + __ b(Condition(1), &seven); \ + __ b(Condition(2), &leftmost1); \ + __ b(Condition(4), &leftmost0); \ + /* ending with 0b000 */ \ + ATOMIC_BIN_OP_BYTE(bin_inst, 0, extract_result); \ + __ b(&done); \ + /* ending in 0b001 to 0b011 */ \ + __ bind(&leftmost0); \ + __ tmll(addr, Operand(3)); \ + __ b(Condition(1), &three); \ + __ b(Condition(2), &two); \ + ATOMIC_BIN_OP_BYTE(bin_inst, 1, extract_result); \ + __ b(&done); \ + /* ending in 0b010 */ \ + __ bind(&two); \ + ATOMIC_BIN_OP_BYTE(bin_inst, 2, extract_result); \ + __ b(&done); \ + /* ending in 0b011 */ \ + __ bind(&three); \ + ATOMIC_BIN_OP_BYTE(bin_inst, 3, extract_result); \ + __ b(&done); \ + /* ending in 0b100 to 0b110 */ \ + __ bind(&leftmost1); \ + __ tmll(addr, Operand(3)); \ + __ b(Condition(8), &four); \ + __ b(Condition(4), &five); \ + ATOMIC_BIN_OP_BYTE(bin_inst, 6, extract_result); \ + __ b(&done); \ + /* ending in 0b100 */ \ + __ bind(&four); \ + ATOMIC_BIN_OP_BYTE(bin_inst, 4, extract_result); \ + __ b(&done); \ + /* ending in 0b101 */ \ + __ bind(&five); \ + ATOMIC_BIN_OP_BYTE(bin_inst, 5, extract_result); \ + __ b(&done); \ + /* ending in 0b111 */ \ + __ bind(&seven); \ + ATOMIC_BIN_OP_BYTE(bin_inst, 7, extract_result); \ + __ bind(&done); \ + } while (false) + +#define ASSEMBLE_ATOMIC64_BINOP_HALFWORD(bin_inst, extract_result) \ + do { \ + Register value = i.InputRegister(2); \ + Register result = i.OutputRegister(0); \ + Register prev = i.TempRegister(0); \ + Register new_val = r0; \ + Register addr = r1; \ + Register temp = kScratchReg; \ + AddressingMode mode = kMode_None; \ + MemOperand op = i.MemoryOperand(&mode); \ + Label done, one, two, three; \ + __ lay(addr, op); \ + __ tmll(addr, Operand(6)); \ + __ b(Condition(1), &three); \ + __ b(Condition(2), &two); \ + __ b(Condition(4), &one); \ + /* ending in 0b00 */ \ + ATOMIC_BIN_OP_HALFWORD(bin_inst, 0, extract_result); \ + __ b(&done); \ + /* ending in 0b01 */ \ + __ bind(&one); \ + ATOMIC_BIN_OP_HALFWORD(bin_inst, 1, extract_result); \ + __ b(&done); \ + /* ending in 0b10 */ \ + __ bind(&two); \ + ATOMIC_BIN_OP_HALFWORD(bin_inst, 2, extract_result); \ + __ b(&done); \ + /* ending in 0b11 */ \ + __ bind(&three); \ + ATOMIC_BIN_OP_HALFWORD(bin_inst, 3, extract_result); \ + __ bind(&done); \ + } while (false) + +#define ASSEMBLE_ATOMIC64_BINOP_WORD(bin_inst, extract_result) \ + do { \ + Register value = i.InputRegister(2); \ + Register result = i.OutputRegister(0); \ + Register prev = i.TempRegister(0); \ + Register new_val = r0; \ + Register addr = r1; \ + Register temp = kScratchReg; \ + AddressingMode mode = kMode_None; \ + MemOperand op = i.MemoryOperand(&mode); \ + Label done, one; \ + __ lay(addr, op); \ + __ tmll(addr, Operand(4)); \ + __ b(Condition(2), &one); \ + /* ending in 0b000 */ \ + ATOMIC_BIN_OP_WORD(bin_inst, 0, extract_result); \ + __ b(&done); \ + __ bind(&one); \ + /* ending in 0b100 */ \ + ATOMIC_BIN_OP_WORD(bin_inst, 1, extract_result); \ + __ bind(&done); \ + } while (false) + +#define ATOMIC64_COMP_EXCHANGE(start, end, shift_amount, offset) \ + { \ + __ lg(temp0, MemOperand(addr, offset)); \ + __ lgr(temp1, temp0); \ + __ RotateInsertSelectBits(temp0, old_val, Operand(start), \ + Operand(end), Operand(shift_amount), false); \ + __ RotateInsertSelectBits(temp1, new_val, Operand(start), \ + Operand(end), Operand(shift_amount), false); \ + __ CmpAndSwap64(temp0, temp1, MemOperand(addr, offset)); \ + __ RotateInsertSelectBits(output, temp0, Operand(start+shift_amount), \ + Operand(end+shift_amount), Operand(64-shift_amount), true); \ + } + +#ifdef V8_TARGET_BIG_ENDIAN +#define ATOMIC64_COMP_EXCHANGE_BYTE(i) \ + { \ + constexpr int idx = (i); \ + constexpr int start = 8 * idx; \ + constexpr int end = start + 7; \ + constexpr int shift_amount = (7 - idx) * 8; \ + ATOMIC64_COMP_EXCHANGE(start, end, shift_amount, -idx); \ + } +#define ATOMIC64_COMP_EXCHANGE_HALFWORD(i) \ + { \ + constexpr int idx = (i); \ + constexpr int start = 16 * idx; \ + constexpr int end = start + 15; \ + constexpr int shift_amount = (3 - idx) * 16; \ + ATOMIC64_COMP_EXCHANGE(start, end, shift_amount, -idx * 2); \ + } +#define ATOMIC64_COMP_EXCHANGE_WORD(i) \ + { \ + constexpr int idx = (i); \ + constexpr int start = 32 * idx; \ + constexpr int end = start + 31; \ + constexpr int shift_amount = (1 - idx) * 32; \ + ATOMIC64_COMP_EXCHANGE(start, end, shift_amount, -idx * 4); \ + } +#else +#define ATOMIC64_COMP_EXCHANGE_BYTE(i) \ + { \ + constexpr int idx = (i); \ + constexpr int start = 32 + 8 * (3 - idx); \ + constexpr int end = start + 7; \ + constexpr int shift_amount = idx * 8; \ + ATOMIC64_COMP_EXCHANGE(start, end, shift_amount, -idx); \ + } +#define ATOMIC64_COMP_EXCHANGE_HALFWORD(i) \ + { \ + constexpr int idx = (i); \ + constexpr int start = 32 + 16 * (1 - idx); \ + constexpr int end = start + 15; \ + constexpr int shift_amount = idx * 16; \ + ATOMIC64_COMP_EXCHANGE(start, end, shift_amount, -idx * 2); \ + } +#define ATOMIC64_COMP_EXCHANGE_WORD(i) \ + { \ + constexpr int idx = (i); \ + constexpr int start = 32 * (1 - idx); \ + constexpr int end = start + 31; \ + constexpr int shift_amount = idx * 32; \ + ATOMIC64_COMP_EXCHANGE(start, end, shift_amount, -idx * 4); \ + } +#endif + +#define ASSEMBLE_ATOMIC64_COMP_EXCHANGE_BYTE(load_and_ext) \ + do { \ + Register old_val = i.InputRegister(0); \ + Register new_val = i.InputRegister(1); \ + Register output = i.OutputRegister(); \ + Register addr = kScratchReg; \ + Register temp0 = r0; \ + Register temp1 = r1; \ + size_t index = 2; \ + AddressingMode mode = kMode_None; \ + MemOperand op = i.MemoryOperand(&mode, &index); \ + Label done, leftmost0, leftmost1, two, three, four, five, seven; \ + __ lay(addr, op); \ + __ tmll(addr, Operand(7)); \ + __ b(Condition(1), &seven); \ + __ b(Condition(2), &leftmost1); \ + __ b(Condition(4), &leftmost0); \ + /* ending with 0b000 */ \ + ATOMIC64_COMP_EXCHANGE_BYTE(0); \ + __ b(&done); \ + /* ending in 0b001 to 0b011 */ \ + __ bind(&leftmost0); \ + __ tmll(addr, Operand(3)); \ + __ b(Condition(1), &three); \ + __ b(Condition(2), &two); \ + ATOMIC64_COMP_EXCHANGE_BYTE(1); \ + __ b(&done); \ + /* ending in 0b010 */ \ + __ bind(&two); \ + ATOMIC64_COMP_EXCHANGE_BYTE(2); \ + __ b(&done); \ + /* ending in 0b011 */ \ + __ bind(&three); \ + ATOMIC64_COMP_EXCHANGE_BYTE(3); \ + __ b(&done); \ + /* ending in 0b100 to 0b110 */ \ + __ bind(&leftmost1); \ + __ tmll(addr, Operand(3)); \ + __ b(Condition(8), &four); \ + __ b(Condition(4), &five); \ + ATOMIC64_COMP_EXCHANGE_BYTE(6); \ + __ b(&done); \ + /* ending in 0b100 */ \ + __ bind(&four); \ + ATOMIC64_COMP_EXCHANGE_BYTE(4); \ + __ b(&done); \ + /* ending in 0b101 */ \ + __ bind(&five); \ + ATOMIC64_COMP_EXCHANGE_BYTE(5); \ + __ b(&done); \ + /* ending in 0b111 */ \ + __ bind(&seven); \ + ATOMIC64_COMP_EXCHANGE_BYTE(7); \ + __ bind(&done); \ + __ load_and_ext(output, output); \ + } while (false) + +#define ASSEMBLE_ATOMIC64_COMP_EXCHANGE_HALFWORD(load_and_ext) \ + do { \ + Register old_val = i.InputRegister(0); \ + Register new_val = i.InputRegister(1); \ + Register output = i.OutputRegister(); \ + Register addr = kScratchReg; \ + Register temp0 = r0; \ + Register temp1 = r1; \ + size_t index = 2; \ + AddressingMode mode = kMode_None; \ + MemOperand op = i.MemoryOperand(&mode, &index); \ + Label done, one, two, three; \ + __ lay(addr, op); \ + __ tmll(addr, Operand(6)); \ + __ b(Condition(1), &three); \ + __ b(Condition(2), &two); \ + __ b(Condition(4), &one); \ + /* ending in 0b00 */ \ + ATOMIC64_COMP_EXCHANGE_HALFWORD(0); \ + __ b(&done); \ + /* ending in 0b01 */ \ + __ bind(&one); \ + ATOMIC64_COMP_EXCHANGE_HALFWORD(1); \ + __ b(&done); \ + /* ending in 0b10 */ \ + __ bind(&two); \ + ATOMIC64_COMP_EXCHANGE_HALFWORD(2); \ + __ b(&done); \ + /* ending in 0b11 */ \ + __ bind(&three); \ + ATOMIC64_COMP_EXCHANGE_HALFWORD(3); \ + __ bind(&done); \ + __ load_and_ext(output, output); \ + } while (false) + +#define ASSEMBLE_ATOMIC64_COMP_EXCHANGE_WORD(load_and_ext) \ + do { \ + Register old_val = i.InputRegister(0); \ + Register new_val = i.InputRegister(1); \ + Register output = i.OutputRegister(); \ + Register addr = kScratchReg; \ + Register temp0 = r0; \ + Register temp1 = r1; \ + size_t index = 2; \ + AddressingMode mode = kMode_None; \ + MemOperand op = i.MemoryOperand(&mode, &index); \ + Label done, one; \ + __ lay(addr, op); \ + __ tmll(addr, Operand(4)); \ + __ b(Condition(2), &one); \ + /* ending in 0b000 */ \ + ATOMIC64_COMP_EXCHANGE_WORD(0); \ + __ b(&done); \ + __ bind(&one); \ + /* ending in 0b100 */ \ + ATOMIC64_COMP_EXCHANGE_WORD(1); \ + __ bind(&done); \ + __ load_and_ext(output, output); \ + } while (false) + +#define ASSEMBLE_ATOMIC64_COMP_EXCHANGE_WORD64() \ + do { \ + Register new_val = i.InputRegister(1); \ + Register output = i.OutputRegister(); \ + Register addr = kScratchReg; \ + size_t index = 2; \ + AddressingMode mode = kMode_None; \ + MemOperand op = i.MemoryOperand(&mode, &index); \ + __ lay(addr, op); \ + __ CmpAndSwap64(output, new_val, MemOperand(addr)); \ + } while (false) + void CodeGenerator::AssembleDeconstructFrame() { __ LeaveFrame(StackFrame::MANUAL); } @@ -2744,6 +3098,260 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kWord32AtomicXorWord32: ASSEMBLE_ATOMIC_BINOP_WORD(lax); break; + case kS390_Word64AtomicLoadUint8: + __ LoadlB(i.OutputRegister(), i.MemoryOperand()); + break; + case kS390_Word64AtomicLoadUint16: + __ LoadLogicalHalfWordP(i.OutputRegister(), i.MemoryOperand()); + break; + case kS390_Word64AtomicLoadUint32: + __ LoadlW(i.OutputRegister(), i.MemoryOperand()); + break; + case kS390_Word64AtomicLoadUint64: + __ lg(i.OutputRegister(), i.MemoryOperand()); + break; + case kS390_Word64AtomicStoreUint8: + __ StoreByte(i.InputRegister(0), i.MemoryOperand(nullptr, 1)); + break; + case kS390_Word64AtomicStoreUint16: + __ StoreHalfWord(i.InputRegister(0), i.MemoryOperand(nullptr, 1)); + break; + case kS390_Word64AtomicStoreUint32: + __ StoreW(i.InputRegister(0), i.MemoryOperand(nullptr, 1)); + break; + case kS390_Word64AtomicStoreUint64: + __ stg(i.InputRegister(0), i.MemoryOperand(nullptr, 1)); + break; +#define ATOMIC64_BINOP_CASE(op, inst) \ + case kS390_Word64Atomic##op##Uint8: \ + ASSEMBLE_ATOMIC64_BINOP_BYTE(inst, [&]() { \ + int rotate_left = shift_amount == 0 ? 0 : 64 - shift_amount; \ + __ RotateInsertSelectBits(result, prev, Operand(56), Operand(63), \ + Operand(static_cast<intptr_t>(rotate_left)), \ + true); \ + }); \ + break; \ + case kS390_Word64Atomic##op##Uint16: \ + ASSEMBLE_ATOMIC64_BINOP_HALFWORD(inst, [&]() { \ + int rotate_left = shift_amount == 0 ? 0 : 64 - shift_amount; \ + __ RotateInsertSelectBits(result, prev, Operand(48), Operand(63), \ + Operand(static_cast<intptr_t>(rotate_left)), \ + true); \ + }); \ + break; \ + case kS390_Word64Atomic##op##Uint32: \ + ASSEMBLE_ATOMIC64_BINOP_WORD(inst, [&]() { \ + int rotate_left = shift_amount == 0 ? 0 : 64 - shift_amount; \ + __ RotateInsertSelectBits(result, prev, Operand(32), Operand(63), \ + Operand(static_cast<intptr_t>(rotate_left)), \ + true); \ + }); \ + break; + ATOMIC64_BINOP_CASE(Add, AddP) + ATOMIC64_BINOP_CASE(Sub, SubP) + ATOMIC64_BINOP_CASE(And, AndP) + ATOMIC64_BINOP_CASE(Or, OrP) + ATOMIC64_BINOP_CASE(Xor, XorP) +#undef ATOMIC64_BINOP_CASE + case kS390_Word64AtomicAddUint64: + ASSEMBLE_ATOMIC_BINOP_WORD64(laag); + break; + case kS390_Word64AtomicSubUint64: + ASSEMBLE_ATOMIC_BINOP_WORD64(LoadAndSub64); + break; + case kS390_Word64AtomicAndUint64: + ASSEMBLE_ATOMIC_BINOP_WORD64(lang); + break; + case kS390_Word64AtomicOrUint64: + ASSEMBLE_ATOMIC_BINOP_WORD64(laog); + break; + case kS390_Word64AtomicXorUint64: + ASSEMBLE_ATOMIC_BINOP_WORD64(laxg); + break; +#define ATOMIC64_EXCHANGE(start, end, shift_amount, offset) \ + { \ + Label do_cs; \ + __ lg(output, MemOperand(r1, offset)); \ + __ bind(&do_cs); \ + __ lgr(r0, output); \ + __ RotateInsertSelectBits(r0, value, Operand(start), Operand(end), \ + Operand(shift_amount), false); \ + __ csg(output, r0, MemOperand(r1, offset)); \ + __ bne(&do_cs, Label::kNear); \ + __ srlg(output, output, Operand(shift_amount)); \ + } +#ifdef V8_TARGET_BIG_ENDIAN +#define ATOMIC64_EXCHANGE_BYTE(i) \ + { \ + constexpr int idx = (i); \ + constexpr int start = 8 * idx; \ + constexpr int end = start + 7; \ + constexpr int shift_amount = (7 - idx) * 8; \ + ATOMIC64_EXCHANGE(start, end, shift_amount, -idx); \ + } +#define ATOMIC64_EXCHANGE_HALFWORD(i) \ + { \ + constexpr int idx = (i); \ + constexpr int start = 16 * idx; \ + constexpr int end = start + 15; \ + constexpr int shift_amount = (3 - idx) * 16; \ + ATOMIC64_EXCHANGE(start, end, shift_amount, -idx * 2); \ + } +#define ATOMIC64_EXCHANGE_WORD(i) \ + { \ + constexpr int idx = (i); \ + constexpr int start = 32 * idx; \ + constexpr int end = start + 31; \ + constexpr int shift_amount = (1 - idx) * 32; \ + ATOMIC64_EXCHANGE(start, end, shift_amount, -idx * 4); \ + } +#else +#define ATOMIC64_EXCHANGE_BYTE(i) \ + { \ + constexpr int idx = (i); \ + constexpr int start = 32 + 8 * (3 - idx); \ + constexpr int end = start + 7; \ + constexpr int shift_amount = idx * 8; \ + ATOMIC64_EXCHANGE(start, end, shift_amount, -idx); \ + } +#define ATOMIC64_EXCHANGE_HALFWORD(i) \ + { \ + constexpr int idx = (i); \ + constexpr int start = 32 + 16 * (1 - idx); \ + constexpr int end = start + 15; \ + constexpr int shift_amount = idx * 16; \ + ATOMIC64_EXCHANGE(start, end, shift_amount, -idx * 2); \ + } +#define ATOMIC64_EXCHANGE_WORD(i) \ + { \ + constexpr int idx = (i); \ + constexpr int start = 32 * (1 - idx); \ + constexpr int end = start + 31; \ + constexpr int shift_amount = idx * 32; \ + ATOMIC64_EXCHANGE(start, end, shift_amount, -idx * 4); \ + } +#endif // V8_TARGET_BIG_ENDIAN + case kS390_Word64AtomicExchangeUint8: { + Register base = i.InputRegister(0); + Register index = i.InputRegister(1); + Register value = i.InputRegister(2); + Register output = i.OutputRegister(); + Label done, leftmost0, leftmost1, two, three, four, five, seven; + __ la(r1, MemOperand(base, index)); + __ tmll(r1, Operand(7)); + __ b(Condition(1), &seven); + __ b(Condition(2), &leftmost1); + __ b(Condition(4), &leftmost0); + /* ending with 0b000 */ + ATOMIC64_EXCHANGE_BYTE(0); + __ b(&done); + /* ending in 0b001 to 0b011 */ + __ bind(&leftmost0); + __ tmll(r1, Operand(3)); + __ b(Condition(1), &three); + __ b(Condition(2), &two); + ATOMIC64_EXCHANGE_BYTE(1); + __ b(&done); + /* ending in 0b010 */ + __ bind(&two); + ATOMIC64_EXCHANGE_BYTE(2); + __ b(&done); + /* ending in 0b011 */ + __ bind(&three); + ATOMIC64_EXCHANGE_BYTE(3); + __ b(&done); + /* ending in 0b100 to 0b110 */ + __ bind(&leftmost1); + __ tmll(r1, Operand(3)); + __ b(Condition(8), &four); + __ b(Condition(4), &five); + ATOMIC64_EXCHANGE_BYTE(6); + __ b(&done); + /* ending in 0b100 */ + __ bind(&four); + ATOMIC64_EXCHANGE_BYTE(4); + __ b(&done); + /* ending in 0b101 */ + __ bind(&five); + ATOMIC64_EXCHANGE_BYTE(5); + __ b(&done); + /* ending in 0b111 */ + __ bind(&seven); + ATOMIC64_EXCHANGE_BYTE(7); + __ bind(&done); + break; + } + case kS390_Word64AtomicExchangeUint16: { + Register base = i.InputRegister(0); + Register index = i.InputRegister(1); + Register value = i.InputRegister(2); + Register output = i.OutputRegister(); + Label done, one, two, three; + __ la(r1, MemOperand(base, index)); + __ tmll(r1, Operand(6)); + __ b(Condition(1), &three); + __ b(Condition(2), &two); + __ b(Condition(4), &one); + /* ending in 0b00 */ + ATOMIC64_EXCHANGE_HALFWORD(0); + __ b(&done); + /* ending in 0b01 */ + __ bind(&one); + ATOMIC64_EXCHANGE_HALFWORD(1); + __ b(&done); + /* ending in 0b10 */ + __ bind(&two); + ATOMIC64_EXCHANGE_HALFWORD(2); + __ b(&done); + /* ending in 0b11 */ + __ bind(&three); + ATOMIC64_EXCHANGE_HALFWORD(3); + __ bind(&done); + break; + } + case kS390_Word64AtomicExchangeUint32: { + Register base = i.InputRegister(0); + Register index = i.InputRegister(1); + Register value = i.InputRegister(2); + Register output = i.OutputRegister(); + Label done, one; + __ la(r1, MemOperand(base, index)); + __ tmll(r1, Operand(4)); + __ b(Condition(2), &one); + /* ending in 0b0 */ + ATOMIC64_EXCHANGE_WORD(0); + __ b(&done); + __ bind(&one); + /* ending in 0b1 */ + ATOMIC64_EXCHANGE_WORD(1); + __ bind(&done); + break; + } + case kS390_Word64AtomicExchangeUint64: { + Register base = i.InputRegister(0); + Register index = i.InputRegister(1); + Register value = i.InputRegister(2); + Register output = i.OutputRegister(); + Label do_cs; + __ la(r1, MemOperand(base, index)); + __ lg(output, MemOperand(r1)); + __ csg(output, value, MemOperand(r1)); + __ bind(&do_cs); + __ bne(&do_cs, Label::kNear); + break; + } + case kS390_Word64AtomicCompareExchangeUint8: + ASSEMBLE_ATOMIC64_COMP_EXCHANGE_BYTE(LoadlB); + break; + case kS390_Word64AtomicCompareExchangeUint16: + ASSEMBLE_ATOMIC64_COMP_EXCHANGE_HALFWORD(LoadLogicalHalfWordP); + break; + case kS390_Word64AtomicCompareExchangeUint32: + ASSEMBLE_ATOMIC64_COMP_EXCHANGE_WORD(LoadlW); + break; + case kS390_Word64AtomicCompareExchangeUint64: + ASSEMBLE_ATOMIC64_COMP_EXCHANGE_WORD64(); + break; default: UNREACHABLE(); break; @@ -2776,7 +3384,8 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { void CodeGenerator::AssembleBranchPoisoning(FlagsCondition condition, Instruction* instr) { // TODO(John) Handle float comparisons (kUnordered[Not]Equal). - if (condition == kUnorderedEqual || condition == kUnorderedNotEqual) { + if (condition == kUnorderedEqual || condition == kUnorderedNotEqual || + condition == kOverflow || condition == kNotOverflow) { return; } @@ -3170,9 +3779,13 @@ void CodeGenerator::AssembleMove(InstructionOperand* source, case Constant::kExternalReference: __ Move(dst, src.ToExternalReference()); break; + case Constant::kDelayedStringConstant: + __ mov(dst, Operand::EmbeddedStringConstant( + src.ToDelayedStringConstant())); + break; case Constant::kHeapObject: { Handle<HeapObject> src_object = src.ToHeapObject(); - Heap::RootListIndex index; + RootIndex index; if (IsMaterializableFromRoot(src_object, &index)) { __ LoadRoot(dst, index); } else { |