| 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 // This file implements the InstARM32 and OperandARM32 classes, | 10 // This file implements the InstARM32 and OperandARM32 classes, | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 60   assert(Inst->getSrcSize() == 2); | 60   assert(Inst->getSrcSize() == 2); | 
| 61   Variable *Dest = Inst->getDest(); | 61   Variable *Dest = Inst->getDest(); | 
| 62   assert(Dest == Inst->getSrc(0)); | 62   assert(Dest == Inst->getSrc(0)); | 
| 63   Operand *Src1 = Inst->getSrc(1); | 63   Operand *Src1 = Inst->getSrc(1); | 
| 64   Str << "\t" << Opcode << "\t"; | 64   Str << "\t" << Opcode << "\t"; | 
| 65   Dest->emit(Func); | 65   Dest->emit(Func); | 
| 66   Str << ", "; | 66   Str << ", "; | 
| 67   Src1->emit(Func); | 67   Src1->emit(Func); | 
| 68 } | 68 } | 
| 69 | 69 | 
|  | 70 void emitThreeAddr(const char *Opcode, const Inst *Inst, const Cfg *Func, | 
|  | 71                    bool SetFlags) { | 
|  | 72   if (!ALLOW_DUMP) | 
|  | 73     return; | 
|  | 74   Ostream &Str = Func->getContext()->getStrEmit(); | 
|  | 75   assert(Inst->getSrcSize() == 2); | 
|  | 76   Variable *Dest = Inst->getDest(); | 
|  | 77   Operand *Src0 = Inst->getSrc(0); | 
|  | 78   Operand *Src1 = Inst->getSrc(1); | 
|  | 79   Str << "\t" << Opcode << (SetFlags ? "s" : "") << "\t"; | 
|  | 80   Dest->emit(Func); | 
|  | 81   Str << ", "; | 
|  | 82   Src0->emit(Func); | 
|  | 83   Str << ", "; | 
|  | 84   Src1->emit(Func); | 
|  | 85 } | 
|  | 86 | 
| 70 OperandARM32Mem::OperandARM32Mem(Cfg * /* Func */, Type Ty, Variable *Base, | 87 OperandARM32Mem::OperandARM32Mem(Cfg * /* Func */, Type Ty, Variable *Base, | 
| 71                                  ConstantInteger32 *ImmOffset, AddrMode Mode) | 88                                  ConstantInteger32 *ImmOffset, AddrMode Mode) | 
| 72     : OperandARM32(kMem, Ty), Base(Base), ImmOffset(ImmOffset), Index(nullptr), | 89     : OperandARM32(kMem, Ty), Base(Base), ImmOffset(ImmOffset), Index(nullptr), | 
| 73       ShiftOp(kNoShift), ShiftAmt(0), Mode(Mode) { | 90       ShiftOp(kNoShift), ShiftAmt(0), Mode(Mode) { | 
| 74   // The Neg modes are only needed for Reg +/- Reg. | 91   // The Neg modes are only needed for Reg +/- Reg. | 
| 75   assert(!isNegAddrMode()); | 92   assert(!isNegAddrMode()); | 
| 76   NumVars = 1; | 93   NumVars = 1; | 
| 77   Vars = &this->Base; | 94   Vars = &this->Base; | 
| 78 } | 95 } | 
| 79 | 96 | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 139   Vars[0] = Reg; | 156   Vars[0] = Reg; | 
| 140   if (ShiftVar) | 157   if (ShiftVar) | 
| 141     Vars[1] = ShiftVar; | 158     Vars[1] = ShiftVar; | 
| 142 } | 159 } | 
| 143 | 160 | 
| 144 InstARM32Ldr::InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem) | 161 InstARM32Ldr::InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem) | 
| 145     : InstARM32(Func, InstARM32::Ldr, 1, Dest) { | 162     : InstARM32(Func, InstARM32::Ldr, 1, Dest) { | 
| 146   addSource(Mem); | 163   addSource(Mem); | 
| 147 } | 164 } | 
| 148 | 165 | 
|  | 166 InstARM32Mla::InstARM32Mla(Cfg *Func, Variable *Dest, Variable *Src0, | 
|  | 167                            Variable *Src1, Variable *Acc) | 
|  | 168     : InstARM32(Func, InstARM32::Mla, 3, Dest) { | 
|  | 169   addSource(Src0); | 
|  | 170   addSource(Src1); | 
|  | 171   addSource(Acc); | 
|  | 172 } | 
|  | 173 | 
| 149 InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) | 174 InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) | 
| 150     : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) { | 175     : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) { | 
| 151   addSource(LR); | 176   addSource(LR); | 
| 152   if (Source) | 177   if (Source) | 
| 153     addSource(Source); | 178     addSource(Source); | 
| 154 } | 179 } | 
| 155 | 180 | 
|  | 181 InstARM32Umull::InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, | 
|  | 182                                Variable *Src0, Variable *Src1) | 
|  | 183     : InstARM32(Func, InstARM32::Umull, 2, DestLo), | 
|  | 184       // DestHi is expected to have a FakeDef inserted by the lowering code. | 
|  | 185       DestHi(DestHi) { | 
|  | 186   addSource(Src0); | 
|  | 187   addSource(Src1); | 
|  | 188 } | 
|  | 189 | 
| 156 // ======================== Dump routines ======================== // | 190 // ======================== Dump routines ======================== // | 
| 157 | 191 | 
| 158 // Two-addr ops | 192 // Two-addr ops | 
| 159 template <> const char *InstARM32Movt::Opcode = "movt"; | 193 template <> const char *InstARM32Movt::Opcode = "movt"; | 
| 160 // Unary ops | 194 // Unary ops | 
| 161 template <> const char *InstARM32Movw::Opcode = "movw"; | 195 template <> const char *InstARM32Movw::Opcode = "movw"; | 
| 162 template <> const char *InstARM32Mvn::Opcode = "mvn"; | 196 template <> const char *InstARM32Mvn::Opcode = "mvn"; | 
| 163 // Mov-like ops | 197 // Mov-like ops | 
| 164 template <> const char *InstARM32Mov::Opcode = "mov"; | 198 template <> const char *InstARM32Mov::Opcode = "mov"; | 
|  | 199 // Three-addr ops | 
|  | 200 template <> const char *InstARM32Adc::Opcode = "adc"; | 
|  | 201 template <> const char *InstARM32Add::Opcode = "add"; | 
|  | 202 template <> const char *InstARM32And::Opcode = "and"; | 
|  | 203 template <> const char *InstARM32Eor::Opcode = "eor"; | 
|  | 204 template <> const char *InstARM32Mul::Opcode = "mul"; | 
|  | 205 template <> const char *InstARM32Orr::Opcode = "orr"; | 
|  | 206 template <> const char *InstARM32Sbc::Opcode = "sbc"; | 
|  | 207 template <> const char *InstARM32Sub::Opcode = "sub"; | 
| 165 | 208 | 
| 166 void InstARM32::dump(const Cfg *Func) const { | 209 void InstARM32::dump(const Cfg *Func) const { | 
| 167   if (!ALLOW_DUMP) | 210   if (!ALLOW_DUMP) | 
| 168     return; | 211     return; | 
| 169   Ostream &Str = Func->getContext()->getStrDump(); | 212   Ostream &Str = Func->getContext()->getStrDump(); | 
| 170   Str << "[ARM32] "; | 213   Str << "[ARM32] "; | 
| 171   Inst::dump(Func); | 214   Inst::dump(Func); | 
| 172 } | 215 } | 
| 173 | 216 | 
| 174 template <> void InstARM32Mov::emit(const Cfg *Func) const { | 217 template <> void InstARM32Mov::emit(const Cfg *Func) const { | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 210   assert(getDest()->hasReg()); | 253   assert(getDest()->hasReg()); | 
| 211   Type Ty = getSrc(0)->getType(); | 254   Type Ty = getSrc(0)->getType(); | 
| 212   Str << "\t" | 255   Str << "\t" | 
| 213       << "ldr" << getWidthString(Ty) << "\t"; | 256       << "ldr" << getWidthString(Ty) << "\t"; | 
| 214   getDest()->emit(Func); | 257   getDest()->emit(Func); | 
| 215   Str << ", "; | 258   Str << ", "; | 
| 216   getSrc(0)->emit(Func); | 259   getSrc(0)->emit(Func); | 
| 217 } | 260 } | 
| 218 | 261 | 
| 219 void InstARM32Ldr::emitIAS(const Cfg *Func) const { | 262 void InstARM32Ldr::emitIAS(const Cfg *Func) const { | 
| 220   assert(getSrcSize() == 2); | 263   assert(getSrcSize() == 1); | 
| 221   (void)Func; | 264   (void)Func; | 
| 222   llvm_unreachable("Not yet implemented"); | 265   llvm_unreachable("Not yet implemented"); | 
| 223 } | 266 } | 
| 224 | 267 | 
| 225 void InstARM32Ldr::dump(const Cfg *Func) const { | 268 void InstARM32Ldr::dump(const Cfg *Func) const { | 
| 226   if (!ALLOW_DUMP) | 269   if (!ALLOW_DUMP) | 
| 227     return; | 270     return; | 
| 228   Ostream &Str = Func->getContext()->getStrDump(); | 271   Ostream &Str = Func->getContext()->getStrDump(); | 
| 229   dumpDest(Func); | 272   dumpDest(Func); | 
| 230   Str << "ldr." << getSrc(0)->getType() << " "; | 273   Str << " = ldr." << getSrc(0)->getType() << " "; | 
| 231   dumpSources(Func); | 274   dumpSources(Func); | 
| 232 } | 275 } | 
| 233 | 276 | 
|  | 277 void InstARM32Mla::emit(const Cfg *Func) const { | 
|  | 278   if (!ALLOW_DUMP) | 
|  | 279     return; | 
|  | 280   Ostream &Str = Func->getContext()->getStrEmit(); | 
|  | 281   assert(getSrcSize() == 3); | 
|  | 282   assert(getDest()->hasReg()); | 
|  | 283   Str << "\t" | 
|  | 284       << "mla" | 
|  | 285       << "\t"; | 
|  | 286   getDest()->emit(Func); | 
|  | 287   Str << ", "; | 
|  | 288   getSrc(0)->emit(Func); | 
|  | 289   Str << ", "; | 
|  | 290   getSrc(1)->emit(Func); | 
|  | 291   Str << ", "; | 
|  | 292   getSrc(2)->emit(Func); | 
|  | 293 } | 
|  | 294 | 
|  | 295 void InstARM32Mla::emitIAS(const Cfg *Func) const { | 
|  | 296   assert(getSrcSize() == 3); | 
|  | 297   (void)Func; | 
|  | 298   llvm_unreachable("Not yet implemented"); | 
|  | 299 } | 
|  | 300 | 
|  | 301 void InstARM32Mla::dump(const Cfg *Func) const { | 
|  | 302   if (!ALLOW_DUMP) | 
|  | 303     return; | 
|  | 304   Ostream &Str = Func->getContext()->getStrDump(); | 
|  | 305   dumpDest(Func); | 
|  | 306   Str << " = mla." << getSrc(0)->getType() << " "; | 
|  | 307   dumpSources(Func); | 
|  | 308 } | 
|  | 309 | 
| 234 template <> void InstARM32Movw::emit(const Cfg *Func) const { | 310 template <> void InstARM32Movw::emit(const Cfg *Func) const { | 
| 235   if (!ALLOW_DUMP) | 311   if (!ALLOW_DUMP) | 
| 236     return; | 312     return; | 
| 237   Ostream &Str = Func->getContext()->getStrEmit(); | 313   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 238   assert(getSrcSize() == 1); | 314   assert(getSrcSize() == 1); | 
| 239   Str << "\t" << Opcode << "\t"; | 315   Str << "\t" << Opcode << "\t"; | 
| 240   getDest()->emit(Func); | 316   getDest()->emit(Func); | 
| 241   Str << ", "; | 317   Str << ", "; | 
| 242   Constant *Src0 = llvm::cast<Constant>(getSrc(0)); | 318   Constant *Src0 = llvm::cast<Constant>(getSrc(0)); | 
| 243   if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { | 319   if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 267 } | 343 } | 
| 268 | 344 | 
| 269 void InstARM32Ret::emit(const Cfg *Func) const { | 345 void InstARM32Ret::emit(const Cfg *Func) const { | 
| 270   if (!ALLOW_DUMP) | 346   if (!ALLOW_DUMP) | 
| 271     return; | 347     return; | 
| 272   assert(getSrcSize() > 0); | 348   assert(getSrcSize() > 0); | 
| 273   Variable *LR = llvm::cast<Variable>(getSrc(0)); | 349   Variable *LR = llvm::cast<Variable>(getSrc(0)); | 
| 274   assert(LR->hasReg()); | 350   assert(LR->hasReg()); | 
| 275   assert(LR->getRegNum() == RegARM32::Reg_lr); | 351   assert(LR->getRegNum() == RegARM32::Reg_lr); | 
| 276   Ostream &Str = Func->getContext()->getStrEmit(); | 352   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 277   Str << "\tbx\t"; | 353   Str << "\t" | 
|  | 354       << "bx" | 
|  | 355       << "\t"; | 
| 278   LR->emit(Func); | 356   LR->emit(Func); | 
| 279 } | 357 } | 
| 280 | 358 | 
| 281 void InstARM32Ret::emitIAS(const Cfg *Func) const { | 359 void InstARM32Ret::emitIAS(const Cfg *Func) const { | 
| 282   (void)Func; | 360   (void)Func; | 
| 283   llvm_unreachable("Not yet implemented"); | 361   llvm_unreachable("Not yet implemented"); | 
| 284 } | 362 } | 
| 285 | 363 | 
| 286 void InstARM32Ret::dump(const Cfg *Func) const { | 364 void InstARM32Ret::dump(const Cfg *Func) const { | 
| 287   if (!ALLOW_DUMP) | 365   if (!ALLOW_DUMP) | 
| 288     return; | 366     return; | 
| 289   Ostream &Str = Func->getContext()->getStrDump(); | 367   Ostream &Str = Func->getContext()->getStrDump(); | 
| 290   Type Ty = (getSrcSize() == 1 ? IceType_void : getSrc(0)->getType()); | 368   Type Ty = (getSrcSize() == 1 ? IceType_void : getSrc(0)->getType()); | 
| 291   Str << "ret." << Ty << " "; | 369   Str << "ret." << Ty << " "; | 
| 292   dumpSources(Func); | 370   dumpSources(Func); | 
| 293 } | 371 } | 
| 294 | 372 | 
|  | 373 void InstARM32Umull::emit(const Cfg *Func) const { | 
|  | 374   if (!ALLOW_DUMP) | 
|  | 375     return; | 
|  | 376   Ostream &Str = Func->getContext()->getStrEmit(); | 
|  | 377   assert(getSrcSize() == 2); | 
|  | 378   assert(getDest()->hasReg()); | 
|  | 379   Str << "\t" | 
|  | 380       << "umull" | 
|  | 381       << "\t"; | 
|  | 382   getDest()->emit(Func); | 
|  | 383   Str << ", "; | 
|  | 384   DestHi->emit(Func); | 
|  | 385   Str << ", "; | 
|  | 386   getSrc(0)->emit(Func); | 
|  | 387   Str << ", "; | 
|  | 388   getSrc(1)->emit(Func); | 
|  | 389 } | 
|  | 390 | 
|  | 391 void InstARM32Umull::emitIAS(const Cfg *Func) const { | 
|  | 392   assert(getSrcSize() == 2); | 
|  | 393   (void)Func; | 
|  | 394   llvm_unreachable("Not yet implemented"); | 
|  | 395 } | 
|  | 396 | 
|  | 397 void InstARM32Umull::dump(const Cfg *Func) const { | 
|  | 398   if (!ALLOW_DUMP) | 
|  | 399     return; | 
|  | 400   Ostream &Str = Func->getContext()->getStrDump(); | 
|  | 401   dumpDest(Func); | 
|  | 402   Str << " = umull." << getSrc(0)->getType() << " "; | 
|  | 403   dumpSources(Func); | 
|  | 404 } | 
|  | 405 | 
| 295 void OperandARM32Mem::emit(const Cfg *Func) const { | 406 void OperandARM32Mem::emit(const Cfg *Func) const { | 
| 296   if (!ALLOW_DUMP) | 407   if (!ALLOW_DUMP) | 
| 297     return; | 408     return; | 
| 298   Ostream &Str = Func->getContext()->getStrEmit(); | 409   Ostream &Str = Func->getContext()->getStrEmit(); | 
| 299   Str << "["; | 410   Str << "["; | 
| 300   getBase()->emit(Func); | 411   getBase()->emit(Func); | 
| 301   switch (getAddrMode()) { | 412   switch (getAddrMode()) { | 
| 302   case PostIndex: | 413   case PostIndex: | 
| 303   case NegPostIndex: | 414   case NegPostIndex: | 
| 304     Str << "], "; | 415     Str << "], "; | 
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 401   if (getShiftOp() != kNoShift) { | 512   if (getShiftOp() != kNoShift) { | 
| 402     Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; | 513     Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; | 
| 403     if (Func) | 514     if (Func) | 
| 404       getShiftAmt()->dump(Func); | 515       getShiftAmt()->dump(Func); | 
| 405     else | 516     else | 
| 406       getShiftAmt()->dump(Str); | 517       getShiftAmt()->dump(Str); | 
| 407   } | 518   } | 
| 408 } | 519 } | 
| 409 | 520 | 
| 410 } // end of namespace Ice | 521 } // end of namespace Ice | 
| OLD | NEW | 
|---|