| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
| 6 | 6 |
| 7 #include "src/arm64/macro-assembler-arm64.h" | 7 #include "src/arm64/macro-assembler-arm64.h" |
| 8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
| 9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 } | 137 } |
| 138 UNREACHABLE(); | 138 UNREACHABLE(); |
| 139 return MemOperand(no_reg); | 139 return MemOperand(no_reg); |
| 140 } | 140 } |
| 141 | 141 |
| 142 MemOperand MemoryOperand(size_t first_index = 0) { | 142 MemOperand MemoryOperand(size_t first_index = 0) { |
| 143 return MemoryOperand(&first_index); | 143 return MemoryOperand(&first_index); |
| 144 } | 144 } |
| 145 | 145 |
| 146 Operand ToOperand(InstructionOperand* op) { | 146 Operand ToOperand(InstructionOperand* op) { |
| 147 if (op->IsRegister()) { | 147 if (op->GeneratesRegister()) { |
| 148 return Operand(ToRegister(op)); | 148 return Operand(ToRegister(op)); |
| 149 } | 149 } |
| 150 return ToImmediate(op); | 150 return ToImmediate(op); |
| 151 } | 151 } |
| 152 | 152 |
| 153 Operand ToOperand32(InstructionOperand* op) { | 153 Operand ToOperand32(InstructionOperand* op) { |
| 154 if (op->IsRegister()) { | 154 if (op->GeneratesRegister()) { |
| 155 return Operand(ToRegister(op).W()); | 155 return Operand(ToRegister(op).W()); |
| 156 } | 156 } |
| 157 return ToImmediate(op); | 157 return ToImmediate(op); |
| 158 } | 158 } |
| 159 | 159 |
| 160 Operand ToImmediate(InstructionOperand* operand) { | 160 Operand ToImmediate(InstructionOperand* operand) { |
| 161 Constant constant = ToConstant(operand); | 161 Constant constant = ToConstant(operand); |
| 162 switch (constant.type()) { | 162 switch (constant.type()) { |
| 163 case Constant::kInt32: | 163 case Constant::kInt32: |
| 164 return Operand(constant.ToInt32()); | 164 return Operand(constant.ToInt32()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 177 case Constant::kRpoNumber: | 177 case Constant::kRpoNumber: |
| 178 UNREACHABLE(); // TODO(dcarney): RPO immediates on arm64. | 178 UNREACHABLE(); // TODO(dcarney): RPO immediates on arm64. |
| 179 break; | 179 break; |
| 180 } | 180 } |
| 181 UNREACHABLE(); | 181 UNREACHABLE(); |
| 182 return Operand(-1); | 182 return Operand(-1); |
| 183 } | 183 } |
| 184 | 184 |
| 185 MemOperand ToMemOperand(InstructionOperand* op, MacroAssembler* masm) const { | 185 MemOperand ToMemOperand(InstructionOperand* op, MacroAssembler* masm) const { |
| 186 DCHECK(op != NULL); | 186 DCHECK(op != NULL); |
| 187 DCHECK(!op->IsRegister()); | 187 DCHECK(!op->GeneratesRegister()); |
| 188 DCHECK(!op->IsDoubleRegister()); | 188 DCHECK(!op->IsDoubleRegister()); |
| 189 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); | 189 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); |
| 190 // The linkage computes where all spill slots are located. | 190 // The linkage computes where all spill slots are located. |
| 191 FrameOffset offset = linkage()->GetFrameOffset( | 191 FrameOffset offset = linkage()->GetFrameOffset( |
| 192 AllocatedOperand::cast(op)->index(), frame(), 0); | 192 AllocatedOperand::cast(op)->index(), frame(), 0); |
| 193 return MemOperand(offset.from_stack_pointer() ? masm->StackPointer() : fp, | 193 return MemOperand(offset.from_stack_pointer() ? masm->StackPointer() : fp, |
| 194 offset.offset()); | 194 offset.offset()); |
| 195 } | 195 } |
| 196 }; | 196 }; |
| 197 | 197 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 __ Cmp(offset, length); \ | 326 __ Cmp(offset, length); \ |
| 327 Label done; \ | 327 Label done; \ |
| 328 __ B(hs, &done); \ | 328 __ B(hs, &done); \ |
| 329 __ asm_instr(value, MemOperand(buffer, offset, UXTW)); \ | 329 __ asm_instr(value, MemOperand(buffer, offset, UXTW)); \ |
| 330 __ Bind(&done); \ | 330 __ Bind(&done); \ |
| 331 } while (0) | 331 } while (0) |
| 332 | 332 |
| 333 | 333 |
| 334 #define ASSEMBLE_SHIFT(asm_instr, width) \ | 334 #define ASSEMBLE_SHIFT(asm_instr, width) \ |
| 335 do { \ | 335 do { \ |
| 336 if (instr->InputAt(1)->IsRegister()) { \ | 336 if (instr->InputAt(1)->GeneratesRegister()) { \ |
| 337 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ | 337 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ |
| 338 i.InputRegister##width(1)); \ | 338 i.InputRegister##width(1)); \ |
| 339 } else { \ | 339 } else { \ |
| 340 uint32_t imm = \ | 340 uint32_t imm = \ |
| 341 static_cast<uint32_t>(i.InputOperand##width(1).ImmediateValue()); \ | 341 static_cast<uint32_t>(i.InputOperand##width(1).ImmediateValue()); \ |
| 342 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ | 342 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ |
| 343 imm % (width)); \ | 343 imm % (width)); \ |
| 344 } \ | 344 } \ |
| 345 } while (0) | 345 } while (0) |
| 346 | 346 |
| (...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1192 __ Ret(); | 1192 __ Ret(); |
| 1193 } | 1193 } |
| 1194 } | 1194 } |
| 1195 | 1195 |
| 1196 | 1196 |
| 1197 void CodeGenerator::AssembleMove(InstructionOperand* source, | 1197 void CodeGenerator::AssembleMove(InstructionOperand* source, |
| 1198 InstructionOperand* destination) { | 1198 InstructionOperand* destination) { |
| 1199 Arm64OperandConverter g(this, NULL); | 1199 Arm64OperandConverter g(this, NULL); |
| 1200 // Dispatch on the source and destination operand kinds. Not all | 1200 // Dispatch on the source and destination operand kinds. Not all |
| 1201 // combinations are possible. | 1201 // combinations are possible. |
| 1202 if (source->IsRegister()) { | 1202 if (source->GeneratesRegister()) { |
| 1203 DCHECK(destination->IsRegister() || destination->IsStackSlot()); | 1203 DCHECK(destination->GeneratesRegister() || destination->IsStackSlot()); |
| 1204 Register src = g.ToRegister(source); | 1204 Register src = g.ToRegister(source); |
| 1205 if (destination->IsRegister()) { | 1205 if (destination->GeneratesRegister()) { |
| 1206 __ Mov(g.ToRegister(destination), src); | 1206 __ Mov(g.ToRegister(destination), src); |
| 1207 } else { | 1207 } else { |
| 1208 __ Str(src, g.ToMemOperand(destination, masm())); | 1208 __ Str(src, g.ToMemOperand(destination, masm())); |
| 1209 } | 1209 } |
| 1210 } else if (source->IsStackSlot()) { | 1210 } else if (source->IsStackSlot()) { |
| 1211 MemOperand src = g.ToMemOperand(source, masm()); | 1211 MemOperand src = g.ToMemOperand(source, masm()); |
| 1212 DCHECK(destination->IsRegister() || destination->IsStackSlot()); | 1212 DCHECK(destination->GeneratesRegister() || destination->IsStackSlot()); |
| 1213 if (destination->IsRegister()) { | 1213 if (destination->GeneratesRegister()) { |
| 1214 __ Ldr(g.ToRegister(destination), src); | 1214 __ Ldr(g.ToRegister(destination), src); |
| 1215 } else { | 1215 } else { |
| 1216 UseScratchRegisterScope scope(masm()); | 1216 UseScratchRegisterScope scope(masm()); |
| 1217 Register temp = scope.AcquireX(); | 1217 Register temp = scope.AcquireX(); |
| 1218 __ Ldr(temp, src); | 1218 __ Ldr(temp, src); |
| 1219 __ Str(temp, g.ToMemOperand(destination, masm())); | 1219 __ Str(temp, g.ToMemOperand(destination, masm())); |
| 1220 } | 1220 } |
| 1221 } else if (source->IsConstant()) { | 1221 } else if (source->IsConstant()) { |
| 1222 Constant src = g.ToConstant(ConstantOperand::cast(source)); | 1222 Constant src = g.ToConstant(ConstantOperand::cast(source)); |
| 1223 if (destination->IsRegister() || destination->IsStackSlot()) { | 1223 if (destination->GeneratesRegister() || destination->IsStackSlot()) { |
| 1224 UseScratchRegisterScope scope(masm()); | 1224 UseScratchRegisterScope scope(masm()); |
| 1225 Register dst = destination->IsRegister() ? g.ToRegister(destination) | 1225 Register dst = destination->GeneratesRegister() |
| 1226 : scope.AcquireX(); | 1226 ? g.ToRegister(destination) |
| 1227 : scope.AcquireX(); |
| 1227 if (src.type() == Constant::kHeapObject) { | 1228 if (src.type() == Constant::kHeapObject) { |
| 1228 Handle<HeapObject> src_object = src.ToHeapObject(); | 1229 Handle<HeapObject> src_object = src.ToHeapObject(); |
| 1229 Heap::RootListIndex index; | 1230 Heap::RootListIndex index; |
| 1230 int offset; | 1231 int offset; |
| 1231 if (IsMaterializableFromFrame(src_object, &offset)) { | 1232 if (IsMaterializableFromFrame(src_object, &offset)) { |
| 1232 __ Ldr(dst, MemOperand(fp, offset)); | 1233 __ Ldr(dst, MemOperand(fp, offset)); |
| 1233 } else if (IsMaterializableFromRoot(src_object, &index)) { | 1234 } else if (IsMaterializableFromRoot(src_object, &index)) { |
| 1234 __ LoadRoot(dst, index); | 1235 __ LoadRoot(dst, index); |
| 1235 } else { | 1236 } else { |
| 1236 __ LoadObject(dst, src_object); | 1237 __ LoadObject(dst, src_object); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1289 UNREACHABLE(); | 1290 UNREACHABLE(); |
| 1290 } | 1291 } |
| 1291 } | 1292 } |
| 1292 | 1293 |
| 1293 | 1294 |
| 1294 void CodeGenerator::AssembleSwap(InstructionOperand* source, | 1295 void CodeGenerator::AssembleSwap(InstructionOperand* source, |
| 1295 InstructionOperand* destination) { | 1296 InstructionOperand* destination) { |
| 1296 Arm64OperandConverter g(this, NULL); | 1297 Arm64OperandConverter g(this, NULL); |
| 1297 // Dispatch on the source and destination operand kinds. Not all | 1298 // Dispatch on the source and destination operand kinds. Not all |
| 1298 // combinations are possible. | 1299 // combinations are possible. |
| 1299 if (source->IsRegister()) { | 1300 if (source->GeneratesRegister()) { |
| 1300 // Register-register. | 1301 // Register-register. |
| 1301 UseScratchRegisterScope scope(masm()); | 1302 UseScratchRegisterScope scope(masm()); |
| 1302 Register temp = scope.AcquireX(); | 1303 Register temp = scope.AcquireX(); |
| 1303 Register src = g.ToRegister(source); | 1304 Register src = g.ToRegister(source); |
| 1304 if (destination->IsRegister()) { | 1305 if (destination->GeneratesRegister()) { |
| 1305 Register dst = g.ToRegister(destination); | 1306 Register dst = g.ToRegister(destination); |
| 1306 __ Mov(temp, src); | 1307 __ Mov(temp, src); |
| 1307 __ Mov(src, dst); | 1308 __ Mov(src, dst); |
| 1308 __ Mov(dst, temp); | 1309 __ Mov(dst, temp); |
| 1309 } else { | 1310 } else { |
| 1310 DCHECK(destination->IsStackSlot()); | 1311 DCHECK(destination->IsStackSlot()); |
| 1311 MemOperand dst = g.ToMemOperand(destination, masm()); | 1312 MemOperand dst = g.ToMemOperand(destination, masm()); |
| 1312 __ Mov(temp, src); | 1313 __ Mov(temp, src); |
| 1313 __ Ldr(src, dst); | 1314 __ Ldr(src, dst); |
| 1314 __ Str(temp, dst); | 1315 __ Str(temp, dst); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1374 } | 1375 } |
| 1375 } | 1376 } |
| 1376 } | 1377 } |
| 1377 } | 1378 } |
| 1378 | 1379 |
| 1379 #undef __ | 1380 #undef __ |
| 1380 | 1381 |
| 1381 } // namespace compiler | 1382 } // namespace compiler |
| 1382 } // namespace internal | 1383 } // namespace internal |
| 1383 } // namespace v8 | 1384 } // namespace v8 |
| OLD | NEW |