| 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 |