| 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/arm/macro-assembler-arm.h" | 7 #include "src/arm/macro-assembler-arm.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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 UNREACHABLE(); | 140 UNREACHABLE(); |
| 141 return MemOperand(r0); | 141 return MemOperand(r0); |
| 142 } | 142 } |
| 143 | 143 |
| 144 MemOperand InputOffset(size_t first_index = 0) { | 144 MemOperand InputOffset(size_t first_index = 0) { |
| 145 return InputOffset(&first_index); | 145 return InputOffset(&first_index); |
| 146 } | 146 } |
| 147 | 147 |
| 148 MemOperand ToMemOperand(InstructionOperand* op) const { | 148 MemOperand ToMemOperand(InstructionOperand* op) const { |
| 149 DCHECK(op != NULL); | 149 DCHECK(op != NULL); |
| 150 DCHECK(!op->IsRegister()); | 150 DCHECK(!op->GeneratesRegister()); |
| 151 DCHECK(!op->IsDoubleRegister()); | 151 DCHECK(!op->IsDoubleRegister()); |
| 152 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); | 152 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); |
| 153 // The linkage computes where all spill slots are located. | 153 // The linkage computes where all spill slots are located. |
| 154 FrameOffset offset = linkage()->GetFrameOffset( | 154 FrameOffset offset = linkage()->GetFrameOffset( |
| 155 AllocatedOperand::cast(op)->index(), frame(), 0); | 155 AllocatedOperand::cast(op)->index(), frame(), 0); |
| 156 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); | 156 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); |
| 157 } | 157 } |
| 158 }; | 158 }; |
| 159 | 159 |
| 160 | 160 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 return kNoCondition; | 234 return kNoCondition; |
| 235 } | 235 } |
| 236 | 236 |
| 237 } // namespace | 237 } // namespace |
| 238 | 238 |
| 239 | 239 |
| 240 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \ | 240 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \ |
| 241 do { \ | 241 do { \ |
| 242 auto result = i.OutputFloat##width##Register(); \ | 242 auto result = i.OutputFloat##width##Register(); \ |
| 243 auto offset = i.InputRegister(0); \ | 243 auto offset = i.InputRegister(0); \ |
| 244 if (instr->InputAt(1)->IsRegister()) { \ | 244 if (instr->InputAt(1)->GeneratesRegister()) { \ |
| 245 __ cmp(offset, i.InputRegister(1)); \ | 245 __ cmp(offset, i.InputRegister(1)); \ |
| 246 } else { \ | 246 } else { \ |
| 247 __ cmp(offset, i.InputImmediate(1)); \ | 247 __ cmp(offset, i.InputImmediate(1)); \ |
| 248 } \ | 248 } \ |
| 249 auto ool = new (zone()) OutOfLineLoadFloat##width(this, result); \ | 249 auto ool = new (zone()) OutOfLineLoadFloat##width(this, result); \ |
| 250 __ b(hs, ool->entry()); \ | 250 __ b(hs, ool->entry()); \ |
| 251 __ vldr(result, i.InputOffset(2)); \ | 251 __ vldr(result, i.InputOffset(2)); \ |
| 252 __ bind(ool->exit()); \ | 252 __ bind(ool->exit()); \ |
| 253 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ | 253 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ |
| 254 } while (0) | 254 } while (0) |
| 255 | 255 |
| 256 | 256 |
| 257 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ | 257 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ |
| 258 do { \ | 258 do { \ |
| 259 auto result = i.OutputRegister(); \ | 259 auto result = i.OutputRegister(); \ |
| 260 auto offset = i.InputRegister(0); \ | 260 auto offset = i.InputRegister(0); \ |
| 261 if (instr->InputAt(1)->IsRegister()) { \ | 261 if (instr->InputAt(1)->GeneratesRegister()) { \ |
| 262 __ cmp(offset, i.InputRegister(1)); \ | 262 __ cmp(offset, i.InputRegister(1)); \ |
| 263 } else { \ | 263 } else { \ |
| 264 __ cmp(offset, i.InputImmediate(1)); \ | 264 __ cmp(offset, i.InputImmediate(1)); \ |
| 265 } \ | 265 } \ |
| 266 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \ | 266 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \ |
| 267 __ b(hs, ool->entry()); \ | 267 __ b(hs, ool->entry()); \ |
| 268 __ asm_instr(result, i.InputOffset(2)); \ | 268 __ asm_instr(result, i.InputOffset(2)); \ |
| 269 __ bind(ool->exit()); \ | 269 __ bind(ool->exit()); \ |
| 270 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ | 270 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ |
| 271 } while (0) | 271 } while (0) |
| 272 | 272 |
| 273 | 273 |
| 274 #define ASSEMBLE_CHECKED_STORE_FLOAT(width) \ | 274 #define ASSEMBLE_CHECKED_STORE_FLOAT(width) \ |
| 275 do { \ | 275 do { \ |
| 276 auto offset = i.InputRegister(0); \ | 276 auto offset = i.InputRegister(0); \ |
| 277 if (instr->InputAt(1)->IsRegister()) { \ | 277 if (instr->InputAt(1)->GeneratesRegister()) { \ |
| 278 __ cmp(offset, i.InputRegister(1)); \ | 278 __ cmp(offset, i.InputRegister(1)); \ |
| 279 } else { \ | 279 } else { \ |
| 280 __ cmp(offset, i.InputImmediate(1)); \ | 280 __ cmp(offset, i.InputImmediate(1)); \ |
| 281 } \ | 281 } \ |
| 282 auto value = i.InputFloat##width##Register(2); \ | 282 auto value = i.InputFloat##width##Register(2); \ |
| 283 __ vstr(value, i.InputOffset(3), lo); \ | 283 __ vstr(value, i.InputOffset(3), lo); \ |
| 284 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ | 284 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ |
| 285 } while (0) | 285 } while (0) |
| 286 | 286 |
| 287 | 287 |
| 288 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ | 288 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ |
| 289 do { \ | 289 do { \ |
| 290 auto offset = i.InputRegister(0); \ | 290 auto offset = i.InputRegister(0); \ |
| 291 if (instr->InputAt(1)->IsRegister()) { \ | 291 if (instr->InputAt(1)->GeneratesRegister()) { \ |
| 292 __ cmp(offset, i.InputRegister(1)); \ | 292 __ cmp(offset, i.InputRegister(1)); \ |
| 293 } else { \ | 293 } else { \ |
| 294 __ cmp(offset, i.InputImmediate(1)); \ | 294 __ cmp(offset, i.InputImmediate(1)); \ |
| 295 } \ | 295 } \ |
| 296 auto value = i.InputRegister(2); \ | 296 auto value = i.InputRegister(2); \ |
| 297 __ asm_instr(value, i.InputOffset(3), lo); \ | 297 __ asm_instr(value, i.InputOffset(3), lo); \ |
| 298 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ | 298 DCHECK_EQ(LeaveCC, i.OutputSBit()); \ |
| 299 } while (0) | 299 } while (0) |
| 300 | 300 |
| 301 | 301 |
| (...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1063 __ Ret(); | 1063 __ Ret(); |
| 1064 } | 1064 } |
| 1065 } | 1065 } |
| 1066 | 1066 |
| 1067 | 1067 |
| 1068 void CodeGenerator::AssembleMove(InstructionOperand* source, | 1068 void CodeGenerator::AssembleMove(InstructionOperand* source, |
| 1069 InstructionOperand* destination) { | 1069 InstructionOperand* destination) { |
| 1070 ArmOperandConverter g(this, NULL); | 1070 ArmOperandConverter g(this, NULL); |
| 1071 // Dispatch on the source and destination operand kinds. Not all | 1071 // Dispatch on the source and destination operand kinds. Not all |
| 1072 // combinations are possible. | 1072 // combinations are possible. |
| 1073 if (source->IsRegister()) { | 1073 if (source->GeneratesRegister()) { |
| 1074 DCHECK(destination->IsRegister() || destination->IsStackSlot()); | 1074 DCHECK(destination->GeneratesRegister() || destination->IsStackSlot()); |
| 1075 Register src = g.ToRegister(source); | 1075 Register src = g.ToRegister(source); |
| 1076 if (destination->IsRegister()) { | 1076 if (destination->GeneratesRegister()) { |
| 1077 __ mov(g.ToRegister(destination), src); | 1077 __ mov(g.ToRegister(destination), src); |
| 1078 } else { | 1078 } else { |
| 1079 __ str(src, g.ToMemOperand(destination)); | 1079 __ str(src, g.ToMemOperand(destination)); |
| 1080 } | 1080 } |
| 1081 } else if (source->IsStackSlot()) { | 1081 } else if (source->IsStackSlot()) { |
| 1082 DCHECK(destination->IsRegister() || destination->IsStackSlot()); | 1082 DCHECK(destination->GeneratesRegister() || destination->IsStackSlot()); |
| 1083 MemOperand src = g.ToMemOperand(source); | 1083 MemOperand src = g.ToMemOperand(source); |
| 1084 if (destination->IsRegister()) { | 1084 if (destination->GeneratesRegister()) { |
| 1085 __ ldr(g.ToRegister(destination), src); | 1085 __ ldr(g.ToRegister(destination), src); |
| 1086 } else { | 1086 } else { |
| 1087 Register temp = kScratchReg; | 1087 Register temp = kScratchReg; |
| 1088 __ ldr(temp, src); | 1088 __ ldr(temp, src); |
| 1089 __ str(temp, g.ToMemOperand(destination)); | 1089 __ str(temp, g.ToMemOperand(destination)); |
| 1090 } | 1090 } |
| 1091 } else if (source->IsConstant()) { | 1091 } else if (source->IsConstant()) { |
| 1092 Constant src = g.ToConstant(source); | 1092 Constant src = g.ToConstant(source); |
| 1093 if (destination->IsRegister() || destination->IsStackSlot()) { | 1093 if (destination->GeneratesRegister() || destination->IsStackSlot()) { |
| 1094 Register dst = | 1094 Register dst = destination->GeneratesRegister() |
| 1095 destination->IsRegister() ? g.ToRegister(destination) : kScratchReg; | 1095 ? g.ToRegister(destination) |
| 1096 : kScratchReg; |
| 1096 switch (src.type()) { | 1097 switch (src.type()) { |
| 1097 case Constant::kInt32: | 1098 case Constant::kInt32: |
| 1098 __ mov(dst, Operand(src.ToInt32())); | 1099 __ mov(dst, Operand(src.ToInt32())); |
| 1099 break; | 1100 break; |
| 1100 case Constant::kInt64: | 1101 case Constant::kInt64: |
| 1101 UNREACHABLE(); | 1102 UNREACHABLE(); |
| 1102 break; | 1103 break; |
| 1103 case Constant::kFloat32: | 1104 case Constant::kFloat32: |
| 1104 __ Move(dst, | 1105 __ Move(dst, |
| 1105 isolate()->factory()->NewNumber(src.ToFloat32(), TENURED)); | 1106 isolate()->factory()->NewNumber(src.ToFloat32(), TENURED)); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1171 UNREACHABLE(); | 1172 UNREACHABLE(); |
| 1172 } | 1173 } |
| 1173 } | 1174 } |
| 1174 | 1175 |
| 1175 | 1176 |
| 1176 void CodeGenerator::AssembleSwap(InstructionOperand* source, | 1177 void CodeGenerator::AssembleSwap(InstructionOperand* source, |
| 1177 InstructionOperand* destination) { | 1178 InstructionOperand* destination) { |
| 1178 ArmOperandConverter g(this, NULL); | 1179 ArmOperandConverter g(this, NULL); |
| 1179 // Dispatch on the source and destination operand kinds. Not all | 1180 // Dispatch on the source and destination operand kinds. Not all |
| 1180 // combinations are possible. | 1181 // combinations are possible. |
| 1181 if (source->IsRegister()) { | 1182 if (source->GeneratesRegister()) { |
| 1182 // Register-register. | 1183 // Register-register. |
| 1183 Register temp = kScratchReg; | 1184 Register temp = kScratchReg; |
| 1184 Register src = g.ToRegister(source); | 1185 Register src = g.ToRegister(source); |
| 1185 if (destination->IsRegister()) { | 1186 if (destination->GeneratesRegister()) { |
| 1186 Register dst = g.ToRegister(destination); | 1187 Register dst = g.ToRegister(destination); |
| 1187 __ Move(temp, src); | 1188 __ Move(temp, src); |
| 1188 __ Move(src, dst); | 1189 __ Move(src, dst); |
| 1189 __ Move(dst, temp); | 1190 __ Move(dst, temp); |
| 1190 } else { | 1191 } else { |
| 1191 DCHECK(destination->IsStackSlot()); | 1192 DCHECK(destination->IsStackSlot()); |
| 1192 MemOperand dst = g.ToMemOperand(destination); | 1193 MemOperand dst = g.ToMemOperand(destination); |
| 1193 __ mov(temp, src); | 1194 __ mov(temp, src); |
| 1194 __ ldr(src, dst); | 1195 __ ldr(src, dst); |
| 1195 __ str(temp, dst); | 1196 __ str(temp, dst); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1268 } | 1269 } |
| 1269 } | 1270 } |
| 1270 } | 1271 } |
| 1271 } | 1272 } |
| 1272 | 1273 |
| 1273 #undef __ | 1274 #undef __ |
| 1274 | 1275 |
| 1275 } // namespace compiler | 1276 } // namespace compiler |
| 1276 } // namespace internal | 1277 } // namespace internal |
| 1277 } // namespace v8 | 1278 } // namespace v8 |
| OLD | NEW |