| OLD | NEW |
| 1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// | 1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// |
| 2 // | 2 // |
| 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 4 // for details. All rights reserved. Use of this source code is governed by a | 4 // for details. All rights reserved. Use of this source code is governed by a |
| 5 // BSD-style license that can be found in the LICENSE file. | 5 // BSD-style license that can be found in the LICENSE file. |
| 6 // | 6 // |
| 7 // Modified by the Subzero authors. | 7 // Modified by the Subzero authors. |
| 8 // | 8 // |
| 9 //===----------------------------------------------------------------------===// | 9 //===----------------------------------------------------------------------===// |
| 10 // | 10 // |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 // Rn should be used, and iiiiiiiiiiii defines the rotated Imm8 value. | 192 // Rn should be used, and iiiiiiiiiiii defines the rotated Imm8 value. |
| 193 DecodedAsImmRegOffset, | 193 DecodedAsImmRegOffset, |
| 194 // Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn, | 194 // Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn, |
| 195 // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift | 195 // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift |
| 196 // kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if | 196 // kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if |
| 197 // writeback to Rn. | 197 // writeback to Rn. |
| 198 DecodedAsShiftRotateImm5, | 198 DecodedAsShiftRotateImm5, |
| 199 // Value=000000000000000000000iiiii0000000 iiii defines the Imm5 value to | 199 // Value=000000000000000000000iiiii0000000 iiii defines the Imm5 value to |
| 200 // shift. | 200 // shift. |
| 201 DecodedAsShiftImm5, | 201 DecodedAsShiftImm5, |
| 202 // i.e. iiiiiss0mmmm where mmmm is the register to rotate, ss is the shift |
| 203 // kind, and iiiii is the shift amount. |
| 204 DecodedAsShiftedRegister, |
| 202 // Value is 32bit integer constant. | 205 // Value is 32bit integer constant. |
| 203 DecodedAsConstI32 | 206 DecodedAsConstI32 |
| 204 }; | 207 }; |
| 205 | 208 |
| 206 // Sets Encoding to a rotated Imm8 encoding of Value, if possible. | 209 // Sets Encoding to a rotated Imm8 encoding of Value, if possible. |
| 207 inline IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) { | 210 inline IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) { |
| 208 assert(RotateAmt < (1 << kRotateBits)); | 211 assert(RotateAmt < (1 << kRotateBits)); |
| 209 assert(Immed8 < (1 << kImmed8Bits)); | 212 assert(Immed8 < (1 << kImmed8Bits)); |
| 210 return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift); | 213 return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift); |
| 211 } | 214 } |
| 212 | 215 |
| 213 // Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5, | 216 // Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5, |
| 214 // tt=Shift, and mmmm=Rm. | 217 // tt=Shift, and mmmm=Rm. |
| 215 IValueT encodeShiftRotateImm5(IValueT Rm, OperandARM32::ShiftKind Shift, | 218 IValueT encodeShiftRotateImm5(IValueT Rm, OperandARM32::ShiftKind Shift, |
| 216 IOffsetT imm5) { | 219 IOffsetT imm5) { |
| 217 (void)kShiftImmBits; | 220 (void)kShiftImmBits; |
| 218 assert(imm5 < (1 << kShiftImmBits)); | 221 assert(imm5 < (1 << kShiftImmBits)); |
| 219 return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm; | 222 return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm; |
| 220 } | 223 } |
| 221 | 224 |
| 222 // Encodes mmmmtt01ssss for data-processing operands where mmmm=Rm, ssss=Rs, and | 225 // Encodes mmmmtt01ssss for data-processing operands where mmmm=Rm, ssss=Rs, and |
| 223 // tt=Shift. | 226 // tt=Shift. |
| 224 IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift, | 227 IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift, |
| 225 IValueT Rs) { | 228 IValueT Rs) { |
| 226 return (Rs << kRsShift) | (encodeShift(Shift) << kShiftShift) | B4 | | 229 return (Rs << kRsShift) | (encodeShift(Shift) << kShiftShift) | B4 | |
| 227 (Rm << kRmShift); | 230 (Rm << kRmShift); |
| 228 } | 231 } |
| 229 | 232 |
| 230 DecodedResult decodeOperand(const Operand *Opnd, IValueT &Value) { | 233 DecodedResult decodeOperand(const Operand *Opnd, IValueT &Value) { |
| 234 Value = 0; // Make sure initialized. |
| 231 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { | 235 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { |
| 232 if (Var->hasReg()) { | 236 if (Var->hasReg()) { |
| 233 Value = Var->getRegNum(); | 237 Value = Var->getRegNum(); |
| 234 return DecodedAsRegister; | 238 return DecodedAsRegister; |
| 235 } | 239 } |
| 236 return CantDecode; | 240 return CantDecode; |
| 237 } | 241 } |
| 238 if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) { | 242 if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) { |
| 239 const IValueT Immed8 = FlexImm->getImm(); | 243 const IValueT Immed8 = FlexImm->getImm(); |
| 240 const IValueT Rotate = FlexImm->getRotateAmt(); | 244 const IValueT Rotate = FlexImm->getRotateAmt(); |
| 241 if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits)))) | 245 if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits)))) |
| 242 return CantDecode; | 246 return CantDecode; |
| 243 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift); | 247 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift); |
| 244 return DecodedAsRotatedImm8; | 248 return DecodedAsRotatedImm8; |
| 245 } | 249 } |
| 246 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) { | 250 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) { |
| 247 Value = Const->getValue(); | 251 Value = Const->getValue(); |
| 248 return DecodedAsConstI32; | 252 return DecodedAsConstI32; |
| 249 } | 253 } |
| 254 if (const auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Opnd)) { |
| 255 Operand *Amt = FlexReg->getShiftAmt(); |
| 256 if (const auto *Imm5 = llvm::dyn_cast<OperandARM32ShAmtImm>(Amt)) { |
| 257 IValueT Rm; |
| 258 if (decodeOperand(FlexReg->getReg(), Rm) != DecodedAsRegister) |
| 259 return CantDecode; |
| 260 Value = |
| 261 encodeShiftRotateImm5(Rm, FlexReg->getShiftOp(), Imm5->getShAmtImm()); |
| 262 return DecodedAsShiftedRegister; |
| 263 } |
| 264 // TODO(kschimpf): Handle case where Amt is a register? |
| 265 } |
| 250 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) { | 266 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) { |
| 251 const IValueT Immed5 = ShImm->getShAmtImm(); | 267 const IValueT Immed5 = ShImm->getShAmtImm(); |
| 252 assert(Immed5 < (1 << kShiftImmBits)); | 268 assert(Immed5 < (1 << kShiftImmBits)); |
| 253 Value = (Immed5 << kShiftImmShift); | 269 Value = (Immed5 << kShiftImmShift); |
| 254 return DecodedAsShiftImm5; | 270 return DecodedAsShiftImm5; |
| 255 } | 271 } |
| 256 return CantDecode; | 272 return CantDecode; |
| 257 } | 273 } |
| 258 | 274 |
| 259 IValueT decodeImmRegOffset(RegARM32::GPRRegister Reg, IOffsetT Offset, | 275 IValueT decodeImmRegOffset(RegARM32::GPRRegister Reg, IOffsetT Offset, |
| 260 OperandARM32Mem::AddrMode Mode) { | 276 OperandARM32Mem::AddrMode Mode) { |
| 261 IValueT Value = Mode | (encodeGPRRegister(Reg) << kRnShift); | 277 IValueT Value = Mode | (encodeGPRRegister(Reg) << kRnShift); |
| 262 if (Offset < 0) { | 278 if (Offset < 0) { |
| 263 Value = (Value ^ U) | -Offset; // Flip U to adjust sign. | 279 Value = (Value ^ U) | -Offset; // Flip U to adjust sign. |
| 264 } else { | 280 } else { |
| 265 Value |= Offset; | 281 Value |= Offset; |
| 266 } | 282 } |
| 267 return Value; | 283 return Value; |
| 268 } | 284 } |
| 269 | 285 |
| 270 // Decodes memory address Opnd, and encodes that information into Value, | 286 // Decodes memory address Opnd, and encodes that information into Value, |
| 271 // based on how ARM represents the address. Returns how the value was encoded. | 287 // based on how ARM represents the address. Returns how the value was encoded. |
| 272 DecodedResult decodeAddress(const Operand *Opnd, IValueT &Value, | 288 DecodedResult decodeAddress(const Operand *Opnd, IValueT &Value, |
| 273 const AssemblerARM32::TargetInfo &TInfo) { | 289 const AssemblerARM32::TargetInfo &TInfo) { |
| 290 Value = 0; // Make sure initialized. |
| 274 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { | 291 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { |
| 275 // Should be a stack variable, with an offset. | 292 // Should be a stack variable, with an offset. |
| 276 if (Var->hasReg()) | 293 if (Var->hasReg()) |
| 277 return CantDecode; | 294 return CantDecode; |
| 278 IOffsetT Offset = Var->getStackOffset(); | 295 IOffsetT Offset = Var->getStackOffset(); |
| 279 if (!Utils::IsAbsoluteUint(12, Offset)) | 296 if (!Utils::IsAbsoluteUint(12, Offset)) |
| 280 return CantDecode; | 297 return CantDecode; |
| 281 int32_t BaseRegNum = Var->getBaseRegNum(); | 298 int32_t BaseRegNum = Var->getBaseRegNum(); |
| 282 if (BaseRegNum == Variable::NoRegister) { | 299 if (BaseRegNum == Variable::NoRegister) { |
| 283 BaseRegNum = TInfo.FrameOrStackReg; | 300 BaseRegNum = TInfo.FrameOrStackReg; |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} | 510 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} |
| 494 // | 511 // |
| 495 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | 512 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 496 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. | 513 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. |
| 497 constexpr IValueT Imm5 = 0; | 514 constexpr IValueT Imm5 = 0; |
| 498 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); | 515 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); |
| 499 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value, | 516 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value, |
| 500 RuleChecks); | 517 RuleChecks); |
| 501 return; | 518 return; |
| 502 } | 519 } |
| 520 case DecodedAsShiftedRegister: { |
| 521 // Form is defined in case DecodedAsRegister. (i.e. XXX (register)). |
| 522 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value, |
| 523 RuleChecks); |
| 524 return; |
| 525 } |
| 503 case DecodedAsConstI32: { | 526 case DecodedAsConstI32: { |
| 504 // See if we can convert this to an XXX (immediate). | 527 // See if we can convert this to an XXX (immediate). |
| 505 IValueT RotateAmt; | 528 IValueT RotateAmt; |
| 506 IValueT Imm8; | 529 IValueT Imm8; |
| 507 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8)) | 530 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8)) |
| 508 return setNeedsTextFixup(); | 531 return setNeedsTextFixup(); |
| 509 Src1Value = encodeRotatedImm8(RotateAmt, Imm8); | 532 Src1Value = encodeRotatedImm8(RotateAmt, Imm8); |
| 510 // Intentionally fall to next case! | 533 // Intentionally fall to next case! |
| 511 } | 534 } |
| 512 case DecodedAsRotatedImm8: { | 535 case DecodedAsRotatedImm8: { |
| (...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1386 // rr defined (RotationValue) rotate. | 1409 // rr defined (RotationValue) rotate. |
| 1387 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21 | B20; | 1410 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21 | B20; |
| 1388 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation); | 1411 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation); |
| 1389 return; | 1412 return; |
| 1390 } | 1413 } |
| 1391 } | 1414 } |
| 1392 } | 1415 } |
| 1393 | 1416 |
| 1394 } // end of namespace ARM32 | 1417 } // end of namespace ARM32 |
| 1395 } // end of namespace Ice | 1418 } // end of namespace Ice |
| OLD | NEW |