| OLD | NEW |
| 1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===// | 1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 /// | 9 /// |
| 10 /// \file | 10 /// \file |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 if (!BuildDefs::dump()) | 144 if (!BuildDefs::dump()) |
| 145 return; | 145 return; |
| 146 Ostream &Str = Func->getContext()->getStrEmit(); | 146 Ostream &Str = Func->getContext()->getStrEmit(); |
| 147 assert(Inst->getSrcSize() == 2); | 147 assert(Inst->getSrcSize() == 2); |
| 148 Str << "\t" << Opcode << Inst->getPredicate() << "\t"; | 148 Str << "\t" << Opcode << Inst->getPredicate() << "\t"; |
| 149 Inst->getSrc(0)->emit(Func); | 149 Inst->getSrc(0)->emit(Func); |
| 150 Str << ", "; | 150 Str << ", "; |
| 151 Inst->getSrc(1)->emit(Func); | 151 Inst->getSrc(1)->emit(Func); |
| 152 } | 152 } |
| 153 | 153 |
| 154 OperandARM32Mem::OperandARM32Mem(Cfg * /* Func */, Type Ty, Variable *Base, | 154 OperandARM32Mem::OperandARM32Mem(Cfg * /* Func */, Type Ty, Variable *MyBase, |
| 155 ConstantInteger32 *ImmOffset, AddrMode Mode) | 155 ConstantInteger32 *MyImmOffset, |
| 156 : OperandARM32(kMem, Ty), Base(Base), ImmOffset(ImmOffset), Index(nullptr), | 156 AddrMode MyMode) |
| 157 ShiftOp(kNoShift), ShiftAmt(0), Mode(Mode) { | 157 : OperandARM32(kMem, Ty), Base(MyBase), ImmOffset(MyImmOffset), |
| 158 Index(nullptr), ShiftOp(kNoShift), ShiftAmt(0), Mode(MyMode) { |
| 158 // The Neg modes are only needed for Reg +/- Reg. | 159 // The Neg modes are only needed for Reg +/- Reg. |
| 159 assert(!isNegAddrMode()); | 160 assert(!isNegAddrMode()); |
| 160 NumVars = 1; | 161 NumVars = 1; |
| 161 Vars = &this->Base; | 162 Vars = &this->Base; |
| 162 } | 163 } |
| 163 | 164 |
| 164 OperandARM32Mem::OperandARM32Mem(Cfg *Func, Type Ty, Variable *Base, | 165 OperandARM32Mem::OperandARM32Mem(Cfg *Func, Type Ty, Variable *MyBase, |
| 165 Variable *Index, ShiftKind ShiftOp, | 166 Variable *MyIndex, ShiftKind MyShiftOp, |
| 166 uint16_t ShiftAmt, AddrMode Mode) | 167 uint16_t MyShiftAmt, AddrMode MyMode) |
| 167 : OperandARM32(kMem, Ty), Base(Base), ImmOffset(0), Index(Index), | 168 : OperandARM32(kMem, Ty), Base(MyBase), ImmOffset(0), Index(MyIndex), |
| 168 ShiftOp(ShiftOp), ShiftAmt(ShiftAmt), Mode(Mode) { | 169 ShiftOp(MyShiftOp), ShiftAmt(MyShiftAmt), Mode(MyMode) { |
| 169 NumVars = 2; | 170 NumVars = 2; |
| 170 Vars = Func->allocateArrayOf<Variable *>(2); | 171 Vars = Func->allocateArrayOf<Variable *>(2); |
| 171 Vars[0] = Base; | 172 Vars[0] = Base; |
| 172 Vars[1] = Index; | 173 Vars[1] = Index; |
| 173 } | 174 } |
| 174 | 175 |
| 175 bool OperandARM32Mem::canHoldOffset(Type Ty, bool SignExt, int32_t Offset) { | 176 bool OperandARM32Mem::canHoldOffset(Type Ty, bool SignExt, int32_t Offset) { |
| 176 int32_t Bits = SignExt ? TypeARM32Attributes[Ty].SExtAddrOffsetBits | 177 int32_t Bits = SignExt ? TypeARM32Attributes[Ty].SExtAddrOffsetBits |
| 177 : TypeARM32Attributes[Ty].ZExtAddrOffsetBits; | 178 : TypeARM32Attributes[Ty].ZExtAddrOffsetBits; |
| 178 if (Bits == 0) | 179 if (Bits == 0) |
| 179 return Offset == 0; | 180 return Offset == 0; |
| 180 // Note that encodings for offsets are sign-magnitude for ARM, so we check | 181 // Note that encodings for offsets are sign-magnitude for ARM, so we check |
| 181 // with IsAbsoluteUint(). | 182 // with IsAbsoluteUint(). |
| 182 if (isScalarFloatingType(Ty)) | 183 if (isScalarFloatingType(Ty)) |
| 183 return Utils::IsAligned(Offset, 4) && Utils::IsAbsoluteUint(Bits, Offset); | 184 return Utils::IsAligned(Offset, 4) && Utils::IsAbsoluteUint(Bits, Offset); |
| 184 return Utils::IsAbsoluteUint(Bits, Offset); | 185 return Utils::IsAbsoluteUint(Bits, Offset); |
| 185 } | 186 } |
| 186 | 187 |
| 187 OperandARM32FlexImm::OperandARM32FlexImm(Cfg * /* Func */, Type Ty, | 188 OperandARM32FlexImm::OperandARM32FlexImm(Cfg * /* Func */, Type Ty, |
| 188 uint32_t Imm, uint32_t RotateAmt) | 189 uint32_t MyImm, uint32_t MyRotateAmt) |
| 189 : OperandARM32Flex(kFlexImm, Ty), Imm(Imm), RotateAmt(RotateAmt) { | 190 : OperandARM32Flex(kFlexImm, Ty), Imm(MyImm), RotateAmt(MyRotateAmt) { |
| 190 NumVars = 0; | 191 NumVars = 0; |
| 191 Vars = nullptr; | 192 Vars = nullptr; |
| 192 } | 193 } |
| 193 | 194 |
| 194 bool OperandARM32FlexImm::canHoldImm(uint32_t Immediate, uint32_t *RotateAmt, | 195 bool OperandARM32FlexImm::canHoldImm(uint32_t Immediate, uint32_t *RotateAmt, |
| 195 uint32_t *Immed_8) { | 196 uint32_t *Immed_8) { |
| 196 // Avoid the more expensive test for frequent small immediate values. | 197 // Avoid the more expensive test for frequent small immediate values. |
| 197 if (Immediate <= 0xFF) { | 198 if (Immediate <= 0xFF) { |
| 198 *RotateAmt = 0; | 199 *RotateAmt = 0; |
| 199 *Immed_8 = Immediate; | 200 *Immed_8 = Immediate; |
| 200 return true; | 201 return true; |
| 201 } | 202 } |
| 202 // Note that immediate must be unsigned for the test to work correctly. | 203 // Note that immediate must be unsigned for the test to work correctly. |
| 203 for (int Rot = 1; Rot < 16; Rot++) { | 204 for (int Rot = 1; Rot < 16; Rot++) { |
| 204 uint32_t Imm8 = Utils::rotateLeft32(Immediate, 2 * Rot); | 205 uint32_t Imm8 = Utils::rotateLeft32(Immediate, 2 * Rot); |
| 205 if (Imm8 <= 0xFF) { | 206 if (Imm8 <= 0xFF) { |
| 206 *RotateAmt = Rot; | 207 *RotateAmt = Rot; |
| 207 *Immed_8 = Imm8; | 208 *Immed_8 = Imm8; |
| 208 return true; | 209 return true; |
| 209 } | 210 } |
| 210 } | 211 } |
| 211 return false; | 212 return false; |
| 212 } | 213 } |
| 213 | 214 |
| 214 OperandARM32FlexReg::OperandARM32FlexReg(Cfg *Func, Type Ty, Variable *Reg, | 215 OperandARM32FlexReg::OperandARM32FlexReg(Cfg *Func, Type Ty, Variable *MyReg, |
| 215 ShiftKind ShiftOp, Operand *ShiftAmt) | 216 ShiftKind MyShiftOp, |
| 216 : OperandARM32Flex(kFlexReg, Ty), Reg(Reg), ShiftOp(ShiftOp), | 217 Operand *MyShiftAmt) |
| 217 ShiftAmt(ShiftAmt) { | 218 : OperandARM32Flex(kFlexReg, Ty), Reg(MyReg), ShiftOp(MyShiftOp), |
| 219 ShiftAmt(MyShiftAmt) { |
| 218 NumVars = 1; | 220 NumVars = 1; |
| 219 Variable *ShiftVar = llvm::dyn_cast_or_null<Variable>(ShiftAmt); | 221 Variable *ShiftVar = llvm::dyn_cast_or_null<Variable>(ShiftAmt); |
| 220 if (ShiftVar) | 222 if (ShiftVar) |
| 221 ++NumVars; | 223 ++NumVars; |
| 222 Vars = Func->allocateArrayOf<Variable *>(NumVars); | 224 Vars = Func->allocateArrayOf<Variable *>(NumVars); |
| 223 Vars[0] = Reg; | 225 Vars[0] = Reg; |
| 224 if (ShiftVar) | 226 if (ShiftVar) |
| 225 Vars[1] = ShiftVar; | 227 Vars[1] = ShiftVar; |
| 226 } | 228 } |
| 227 | 229 |
| 228 InstARM32AdjustStack::InstARM32AdjustStack(Cfg *Func, Variable *SP, | 230 InstARM32AdjustStack::InstARM32AdjustStack(Cfg *Func, Variable *SP, |
| 229 SizeT Amount, Operand *SrcAmount) | 231 SizeT MyAmount, Operand *SrcAmount) |
| 230 : InstARM32(Func, InstARM32::Adjuststack, 2, SP), Amount(Amount) { | 232 : InstARM32(Func, InstARM32::Adjuststack, 2, SP), Amount(MyAmount) { |
| 231 addSource(SP); | 233 addSource(SP); |
| 232 addSource(SrcAmount); | 234 addSource(SrcAmount); |
| 233 } | 235 } |
| 234 | 236 |
| 235 InstARM32Br::InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, | 237 InstARM32Br::InstARM32Br(Cfg *Func, const CfgNode *MyTargetTrue, |
| 236 const CfgNode *TargetFalse, | 238 const CfgNode *MyTargetFalse, |
| 237 const InstARM32Label *Label, CondARM32::Cond Pred) | 239 const InstARM32Label *MyLabel, CondARM32::Cond Pred) |
| 238 : InstARM32Pred(Func, InstARM32::Br, 0, nullptr, Pred), | 240 : InstARM32Pred(Func, InstARM32::Br, 0, nullptr, Pred), |
| 239 TargetTrue(TargetTrue), TargetFalse(TargetFalse), Label(Label) {} | 241 TargetTrue(MyTargetTrue), TargetFalse(MyTargetFalse), Label(MyLabel) {} |
| 240 | 242 |
| 241 bool InstARM32Br::optimizeBranch(const CfgNode *NextNode) { | 243 bool InstARM32Br::optimizeBranch(const CfgNode *NextNode) { |
| 242 // If there is no next block, then there can be no fallthrough to | 244 // If there is no next block, then there can be no fallthrough to |
| 243 // optimize. | 245 // optimize. |
| 244 if (NextNode == nullptr) | 246 if (NextNode == nullptr) |
| 245 return false; | 247 return false; |
| 246 // Intra-block conditional branches can't be optimized. | 248 // Intra-block conditional branches can't be optimized. |
| 247 if (Label) | 249 if (Label) |
| 248 return false; | 250 return false; |
| 249 // If there is no fallthrough node, such as a non-default case label | 251 // If there is no fallthrough node, such as a non-default case label |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 IceString InstARM32Label::getName(const Cfg *Func) const { | 303 IceString InstARM32Label::getName(const Cfg *Func) const { |
| 302 return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number); | 304 return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number); |
| 303 } | 305 } |
| 304 | 306 |
| 305 InstARM32Ldr::InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, | 307 InstARM32Ldr::InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, |
| 306 CondARM32::Cond Predicate) | 308 CondARM32::Cond Predicate) |
| 307 : InstARM32Pred(Func, InstARM32::Ldr, 1, Dest, Predicate) { | 309 : InstARM32Pred(Func, InstARM32::Ldr, 1, Dest, Predicate) { |
| 308 addSource(Mem); | 310 addSource(Mem); |
| 309 } | 311 } |
| 310 | 312 |
| 311 InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests) | 313 InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &MyDests) |
| 312 : InstARM32(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) { | 314 : InstARM32(Func, InstARM32::Pop, 0, nullptr), Dests(MyDests) { |
| 313 // Track modifications to Dests separately via FakeDefs. | 315 // Track modifications to Dests separately via FakeDefs. |
| 314 // Also, a pop instruction affects the stack pointer and so it should not | 316 // Also, a pop instruction affects the stack pointer and so it should not |
| 315 // be allowed to be automatically dead-code eliminated. This is automatic | 317 // be allowed to be automatically dead-code eliminated. This is automatic |
| 316 // since we leave the Dest as nullptr. | 318 // since we leave the Dest as nullptr. |
| 317 } | 319 } |
| 318 | 320 |
| 319 InstARM32Push::InstARM32Push(Cfg *Func, const VarList &Srcs) | 321 InstARM32Push::InstARM32Push(Cfg *Func, const VarList &Srcs) |
| 320 : InstARM32(Func, InstARM32::Push, Srcs.size(), nullptr) { | 322 : InstARM32(Func, InstARM32::Push, Srcs.size(), nullptr) { |
| 321 for (Variable *Source : Srcs) | 323 for (Variable *Source : Srcs) |
| 322 addSource(Source); | 324 addSource(Source); |
| 323 } | 325 } |
| 324 | 326 |
| 325 InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) | 327 InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) |
| 326 : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) { | 328 : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) { |
| 327 addSource(LR); | 329 addSource(LR); |
| 328 if (Source) | 330 if (Source) |
| 329 addSource(Source); | 331 addSource(Source); |
| 330 } | 332 } |
| 331 | 333 |
| 332 InstARM32Str::InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, | 334 InstARM32Str::InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, |
| 333 CondARM32::Cond Predicate) | 335 CondARM32::Cond Predicate) |
| 334 : InstARM32Pred(Func, InstARM32::Str, 2, nullptr, Predicate) { | 336 : InstARM32Pred(Func, InstARM32::Str, 2, nullptr, Predicate) { |
| 335 addSource(Value); | 337 addSource(Value); |
| 336 addSource(Mem); | 338 addSource(Mem); |
| 337 } | 339 } |
| 338 | 340 |
| 339 InstARM32Trap::InstARM32Trap(Cfg *Func) | 341 InstARM32Trap::InstARM32Trap(Cfg *Func) |
| 340 : InstARM32(Func, InstARM32::Trap, 0, nullptr) {} | 342 : InstARM32(Func, InstARM32::Trap, 0, nullptr) {} |
| 341 | 343 |
| 342 InstARM32Umull::InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, | 344 InstARM32Umull::InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *MyDestHi, |
| 343 Variable *Src0, Variable *Src1, | 345 Variable *Src0, Variable *Src1, |
| 344 CondARM32::Cond Predicate) | 346 CondARM32::Cond Predicate) |
| 345 : InstARM32Pred(Func, InstARM32::Umull, 2, DestLo, Predicate), | 347 : InstARM32Pred(Func, InstARM32::Umull, 2, DestLo, Predicate), |
| 346 // DestHi is expected to have a FakeDef inserted by the lowering code. | 348 // DestHi is expected to have a FakeDef inserted by the lowering code. |
| 347 DestHi(DestHi) { | 349 DestHi(MyDestHi) { |
| 348 addSource(Src0); | 350 addSource(Src0); |
| 349 addSource(Src1); | 351 addSource(Src1); |
| 350 } | 352 } |
| 351 | 353 |
| 352 // ======================== Dump routines ======================== // | 354 // ======================== Dump routines ======================== // |
| 353 | 355 |
| 354 // Two-addr ops | 356 // Two-addr ops |
| 355 template <> const char *InstARM32Movt::Opcode = "movt"; | 357 template <> const char *InstARM32Movt::Opcode = "movt"; |
| 356 // Unary ops | 358 // Unary ops |
| 357 template <> const char *InstARM32Movw::Opcode = "movw"; | 359 template <> const char *InstARM32Movw::Opcode = "movw"; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 Inst::dump(Func); | 396 Inst::dump(Func); |
| 395 } | 397 } |
| 396 | 398 |
| 397 template <> void InstARM32Mov::emit(const Cfg *Func) const { | 399 template <> void InstARM32Mov::emit(const Cfg *Func) const { |
| 398 if (!BuildDefs::dump()) | 400 if (!BuildDefs::dump()) |
| 399 return; | 401 return; |
| 400 Ostream &Str = Func->getContext()->getStrEmit(); | 402 Ostream &Str = Func->getContext()->getStrEmit(); |
| 401 assert(getSrcSize() == 1); | 403 assert(getSrcSize() == 1); |
| 402 Variable *Dest = getDest(); | 404 Variable *Dest = getDest(); |
| 403 if (Dest->hasReg()) { | 405 if (Dest->hasReg()) { |
| 404 IceString Opcode = "mov"; | 406 IceString MyOpcode = "mov"; |
| 405 Operand *Src0 = getSrc(0); | 407 Operand *Src0 = getSrc(0); |
| 406 if (const auto *Src0V = llvm::dyn_cast<Variable>(Src0)) { | 408 if (const auto *Src0V = llvm::dyn_cast<Variable>(Src0)) { |
| 407 if (!Src0V->hasReg()) { | 409 if (!Src0V->hasReg()) { |
| 408 Opcode = IceString("ldr"); // Always use the whole stack slot. | 410 MyOpcode = IceString("ldr"); // Always use the whole stack slot. |
| 409 } | 411 } |
| 410 } else { | 412 } else { |
| 411 if (llvm::isa<OperandARM32Mem>(Src0)) | 413 if (llvm::isa<OperandARM32Mem>(Src0)) |
| 412 Opcode = IceString("ldr") + getWidthString(Dest->getType()); | 414 MyOpcode = IceString("ldr") + getWidthString(Dest->getType()); |
| 413 } | 415 } |
| 414 Str << "\t" << Opcode << getPredicate() << "\t"; | 416 Str << "\t" << MyOpcode << getPredicate() << "\t"; |
| 415 getDest()->emit(Func); | 417 getDest()->emit(Func); |
| 416 Str << ", "; | 418 Str << ", "; |
| 417 getSrc(0)->emit(Func); | 419 getSrc(0)->emit(Func); |
| 418 } else { | 420 } else { |
| 419 Variable *Src0 = llvm::cast<Variable>(getSrc(0)); | 421 Variable *Src0 = llvm::cast<Variable>(getSrc(0)); |
| 420 assert(Src0->hasReg()); | 422 assert(Src0->hasReg()); |
| 421 Str << "\t" | 423 Str << "\t" |
| 422 << "str" << getPredicate() << "\t"; | 424 << "str" << getPredicate() << "\t"; |
| 423 Src0->emit(Func); | 425 Src0->emit(Func); |
| 424 Str << ", "; | 426 Str << ", "; |
| (...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 } else { | 891 } else { |
| 890 getOffset()->dump(Func, Str); | 892 getOffset()->dump(Func, Str); |
| 891 } | 893 } |
| 892 Str << "] AddrMode==" << getAddrMode(); | 894 Str << "] AddrMode==" << getAddrMode(); |
| 893 } | 895 } |
| 894 | 896 |
| 895 void OperandARM32FlexImm::emit(const Cfg *Func) const { | 897 void OperandARM32FlexImm::emit(const Cfg *Func) const { |
| 896 if (!BuildDefs::dump()) | 898 if (!BuildDefs::dump()) |
| 897 return; | 899 return; |
| 898 Ostream &Str = Func->getContext()->getStrEmit(); | 900 Ostream &Str = Func->getContext()->getStrEmit(); |
| 899 uint32_t Imm = getImm(); | 901 Str << "#" << Utils::rotateRight32(getImm(), 2 * getRotateAmt()); |
| 900 uint32_t RotateAmt = getRotateAmt(); | |
| 901 Str << "#" << Utils::rotateRight32(Imm, 2 * RotateAmt); | |
| 902 } | 902 } |
| 903 | 903 |
| 904 void OperandARM32FlexImm::dump(const Cfg * /* Func */, Ostream &Str) const { | 904 void OperandARM32FlexImm::dump(const Cfg * /* Func */, Ostream &Str) const { |
| 905 if (!BuildDefs::dump()) | 905 if (!BuildDefs::dump()) |
| 906 return; | 906 return; |
| 907 uint32_t Imm = getImm(); | 907 Str << "#(" << getImm() << " ror 2*" << getRotateAmt() << ")"; |
| 908 uint32_t RotateAmt = getRotateAmt(); | |
| 909 Str << "#(" << Imm << " ror 2*" << RotateAmt << ")"; | |
| 910 } | 908 } |
| 911 | 909 |
| 912 void OperandARM32FlexReg::emit(const Cfg *Func) const { | 910 void OperandARM32FlexReg::emit(const Cfg *Func) const { |
| 913 if (!BuildDefs::dump()) | 911 if (!BuildDefs::dump()) |
| 914 return; | 912 return; |
| 915 Ostream &Str = Func->getContext()->getStrEmit(); | 913 Ostream &Str = Func->getContext()->getStrEmit(); |
| 916 getReg()->emit(Func); | 914 getReg()->emit(Func); |
| 917 if (getShiftOp() != kNoShift) { | 915 if (getShiftOp() != kNoShift) { |
| 918 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; | 916 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; |
| 919 getShiftAmt()->emit(Func); | 917 getShiftAmt()->emit(Func); |
| 920 } | 918 } |
| 921 } | 919 } |
| 922 | 920 |
| 923 void OperandARM32FlexReg::dump(const Cfg *Func, Ostream &Str) const { | 921 void OperandARM32FlexReg::dump(const Cfg *Func, Ostream &Str) const { |
| 924 if (!BuildDefs::dump()) | 922 if (!BuildDefs::dump()) |
| 925 return; | 923 return; |
| 926 Variable *Reg = getReg(); | |
| 927 if (Func) | 924 if (Func) |
| 928 Reg->dump(Func); | 925 Reg->dump(Func); |
| 929 else | 926 else |
| 930 Reg->dump(Str); | 927 Reg->dump(Str); |
| 931 if (getShiftOp() != kNoShift) { | 928 if (getShiftOp() != kNoShift) { |
| 932 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; | 929 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; |
| 933 if (Func) | 930 if (Func) |
| 934 getShiftAmt()->dump(Func); | 931 getShiftAmt()->dump(Func); |
| 935 else | 932 else |
| 936 getShiftAmt()->dump(Str); | 933 getShiftAmt()->dump(Str); |
| 937 } | 934 } |
| 938 } | 935 } |
| 939 | 936 |
| 940 } // end of namespace Ice | 937 } // end of namespace Ice |
| OLD | NEW |