| Index: src/compiler/arm64/code-generator-arm64.cc
|
| diff --git a/src/compiler/arm64/code-generator-arm64.cc b/src/compiler/arm64/code-generator-arm64.cc
|
| index 87a2f41c9e98f321278ecbe72e53b70a7a3bcb51..91bbc2d1d919efbbe4daaddcad8e638573deed5a 100644
|
| --- a/src/compiler/arm64/code-generator-arm64.cc
|
| +++ b/src/compiler/arm64/code-generator-arm64.cc
|
| @@ -129,8 +129,8 @@ class Arm64OperandConverter V8_FINAL : public InstructionOperandConverter {
|
| // Assembles an instruction after register allocation, producing machine code.
|
| void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
| Arm64OperandConverter i(this, instr);
|
| -
|
| - switch (ArchOpcodeField::decode(instr->opcode())) {
|
| + InstructionCode opcode = instr->opcode();
|
| + switch (ArchOpcodeField::decode(opcode)) {
|
| case kArchJmp:
|
| __ B(code_->GetLabel(i.InputBlock(0)));
|
| break;
|
| @@ -153,7 +153,12 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
| __ Add(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
|
| break;
|
| case kArm64Add32:
|
| - __ Add(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand32(1));
|
| + if (FlagsModeField::decode(opcode) != kFlags_none) {
|
| + __ Adds(i.OutputRegister32(), i.InputRegister32(0),
|
| + i.InputOperand32(1));
|
| + } else {
|
| + __ Add(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand32(1));
|
| + }
|
| break;
|
| case kArm64And:
|
| __ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
|
| @@ -507,6 +512,12 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
|
| case kUnsignedGreaterThan:
|
| __ B(hi, tlabel);
|
| break;
|
| + case kOverflow:
|
| + __ B(vs, tlabel);
|
| + break;
|
| + case kNotOverflow:
|
| + __ B(vc, tlabel);
|
| + break;
|
| }
|
| if (!fallthru) __ B(flabel); // no fallthru to flabel.
|
| __ Bind(&done);
|
| @@ -519,9 +530,11 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
|
| Arm64OperandConverter i(this, instr);
|
| Label done;
|
|
|
| - // Materialize a full 64-bit 1 or 0 value.
|
| + // Materialize a full 64-bit 1 or 0 value. The result register is always the
|
| + // last output of the instruction.
|
| Label check;
|
| - Register reg = i.OutputRegister();
|
| + ASSERT_NE(0, instr->OutputCount());
|
| + Register reg = i.OutputRegister(instr->OutputCount() - 1);
|
| Condition cc = nv;
|
| switch (condition) {
|
| case kUnorderedEqual:
|
| @@ -584,6 +597,12 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
|
| case kUnsignedGreaterThan:
|
| cc = hi;
|
| break;
|
| + case kOverflow:
|
| + cc = vs;
|
| + break;
|
| + case kNotOverflow:
|
| + cc = vc;
|
| + break;
|
| }
|
| __ bind(&check);
|
| __ Cset(reg, cc);
|
|
|