John Porto | 2da710c | 2015-06-29 07:57:02 -0700 | [diff] [blame] | 1 | //===- subzero/src/IceAssemblerMIPS32.h - Assembler for MIPS ----*- C++ -*-===// |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 2 | // |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 3 | // The Subzero Code Generator |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 9 | /// |
| 10 | /// \file |
Jim Stichnoth | 92a6e5b | 2015-12-02 16:52:44 -0800 | [diff] [blame] | 11 | /// \brief Declares the Assembler class for MIPS32. |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 12 | /// |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 13 | //===----------------------------------------------------------------------===// |
| 14 | |
John Porto | 2da710c | 2015-06-29 07:57:02 -0700 | [diff] [blame] | 15 | #ifndef SUBZERO_SRC_ICEASSEMBLERMIPS32_H |
| 16 | #define SUBZERO_SRC_ICEASSEMBLERMIPS32_H |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 17 | |
| 18 | #include "IceAssembler.h" |
| 19 | #include "IceDefs.h" |
| 20 | #include "IceFixups.h" |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 21 | #include "IceInstMIPS32.h" |
| 22 | #include "IceTargetLowering.h" |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 23 | |
| 24 | namespace Ice { |
| 25 | namespace MIPS32 { |
| 26 | |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 27 | using IValueT = uint32_t; |
| 28 | using IOffsetT = int32_t; |
| 29 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 30 | enum FPInstDataFormat { |
| 31 | SinglePrecision = 16, |
| 32 | DoublePrecision = 17, |
| 33 | Word = 20, |
| 34 | Long = 21 |
| 35 | }; |
| 36 | |
Jaydeep Patil | 130aca7 | 2016-10-28 05:30:54 -0700 | [diff] [blame] | 37 | class MIPS32Fixup final : public AssemblerFixup { |
| 38 | MIPS32Fixup &operator=(const MIPS32Fixup &) = delete; |
| 39 | MIPS32Fixup(const MIPS32Fixup &) = default; |
| 40 | |
| 41 | public: |
| 42 | MIPS32Fixup() = default; |
| 43 | size_t emit(GlobalContext *Ctx, const Assembler &Asm) const final; |
| 44 | void emitOffset(Assembler *Asm) const; |
| 45 | }; |
| 46 | |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 47 | class AssemblerMIPS32 : public Assembler { |
| 48 | AssemblerMIPS32(const AssemblerMIPS32 &) = delete; |
| 49 | AssemblerMIPS32 &operator=(const AssemblerMIPS32 &) = delete; |
| 50 | |
| 51 | public: |
Jim Stichnoth | 5bff61c | 2015-10-28 09:26:00 -0700 | [diff] [blame] | 52 | explicit AssemblerMIPS32(bool use_far_branches = false) |
| 53 | : Assembler(Asm_MIPS32) { |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 54 | // This mode is only needed and implemented for MIPS32 and ARM. |
| 55 | assert(!use_far_branches); |
| 56 | (void)use_far_branches; |
| 57 | } |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 58 | ~AssemblerMIPS32() override { |
| 59 | if (BuildDefs::asserts()) { |
| 60 | for (const Label *Label : CfgNodeLabels) { |
| 61 | Label->finalCheck(); |
| 62 | } |
| 63 | for (const Label *Label : LocalLabels) { |
| 64 | Label->finalCheck(); |
| 65 | } |
| 66 | } |
| 67 | } |
| 68 | |
Jaydeep Patil | 130aca7 | 2016-10-28 05:30:54 -0700 | [diff] [blame] | 69 | MIPS32Fixup *createMIPS32Fixup(const RelocOp Reloc, const Constant *RelOp); |
| 70 | |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 71 | void trap(); |
| 72 | |
| 73 | void nop(); |
| 74 | |
Srdjan Obucina | 623f8ce | 2016-09-26 20:03:20 -0700 | [diff] [blame] | 75 | void emitRsRt(IValueT Opcode, const Operand *OpRs, const Operand *OpRt, |
| 76 | const char *InsnName); |
| 77 | |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 78 | void emitRtRsImm16(IValueT Opcode, const Operand *OpRt, const Operand *OpRs, |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 79 | uint32_t Imm, const char *InsnName); |
| 80 | |
Jaydeep Patil | 130aca7 | 2016-10-28 05:30:54 -0700 | [diff] [blame] | 81 | void emitRtRsImm16Rel(IValueT Opcode, const Operand *OpRt, |
| 82 | const Operand *OpRs, const Operand *OpImm, |
| 83 | const RelocOp Reloc, const char *InsnName); |
| 84 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 85 | void emitFtRsImm16(IValueT Opcode, const Operand *OpFt, const Operand *OpRs, |
| 86 | uint32_t Imm, const char *InsnName); |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 87 | |
| 88 | void emitRdRtSa(IValueT Opcode, const Operand *OpRd, const Operand *OpRt, |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 89 | uint32_t Sa, const char *InsnName); |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 90 | |
| 91 | void emitRdRsRt(IValueT Opcode, const Operand *OpRd, const Operand *OpRs, |
| 92 | const Operand *OpRt, const char *InsnName); |
| 93 | |
Srdjan Obucina | 8d16c1d | 2016-09-20 08:44:44 -0700 | [diff] [blame] | 94 | void emitCOP1Fcmp(IValueT Opcode, FPInstDataFormat Format, |
| 95 | const Operand *OpFs, const Operand *OpFt, IValueT CC, |
| 96 | const char *InsnName); |
| 97 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 98 | void emitCOP1FmtFsFd(IValueT Opcode, FPInstDataFormat Format, |
| 99 | const Operand *OpFd, const Operand *OpFs, |
| 100 | const char *InsnName); |
| 101 | |
| 102 | void emitCOP1FmtFtFsFd(IValueT Opcode, FPInstDataFormat Format, |
| 103 | const Operand *OpFd, const Operand *OpFs, |
| 104 | const Operand *OpFt, const char *InsnName); |
| 105 | |
| 106 | void emitCOP1FmtRtFsFd(IValueT Opcode, FPInstDataFormat Format, |
| 107 | const Operand *OpFd, const Operand *OpFs, |
| 108 | const Operand *OpRt, const char *InsnName); |
| 109 | |
| 110 | void emitCOP1MovRtFs(IValueT Opcode, const Operand *OpRt, const Operand *OpFs, |
| 111 | const char *InsnName); |
| 112 | |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 113 | void emitBr(const CondMIPS32::Cond Cond, const Operand *OpRs, |
| 114 | const Operand *OpRt, IOffsetT Offset); |
| 115 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 116 | void abs_d(const Operand *OpFd, const Operand *OpFs); |
| 117 | |
| 118 | void abs_s(const Operand *OpFd, const Operand *OpFs); |
| 119 | |
Jaydeep Patil | 130aca7 | 2016-10-28 05:30:54 -0700 | [diff] [blame] | 120 | void addi(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| 121 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 122 | void add_d(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt); |
| 123 | |
| 124 | void add_s(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt); |
| 125 | |
| 126 | void addu(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 127 | |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 128 | void addiu(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| 129 | |
Jaydeep Patil | 130aca7 | 2016-10-28 05:30:54 -0700 | [diff] [blame] | 130 | void addiu(const Operand *OpRt, const Operand *OpRs, const Operand *OpImm, |
| 131 | const RelocOp Reloc); |
| 132 | |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 133 | void and_(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 134 | |
| 135 | void andi(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| 136 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 137 | void b(Label *TargetLabel); |
| 138 | |
Srdjan Obucina | 8d16c1d | 2016-09-20 08:44:44 -0700 | [diff] [blame] | 139 | void c_eq_d(const Operand *OpFd, const Operand *OpFs); |
| 140 | |
| 141 | void c_eq_s(const Operand *OpFd, const Operand *OpFs); |
| 142 | |
| 143 | void c_ole_d(const Operand *OpFd, const Operand *OpFs); |
| 144 | |
| 145 | void c_ole_s(const Operand *OpFd, const Operand *OpFs); |
| 146 | |
| 147 | void c_olt_d(const Operand *OpFd, const Operand *OpFs); |
| 148 | |
| 149 | void c_olt_s(const Operand *OpFd, const Operand *OpFs); |
| 150 | |
| 151 | void c_ueq_d(const Operand *OpFd, const Operand *OpFs); |
| 152 | |
| 153 | void c_ueq_s(const Operand *OpFd, const Operand *OpFs); |
| 154 | |
| 155 | void c_ule_d(const Operand *OpFd, const Operand *OpFs); |
| 156 | |
| 157 | void c_ule_s(const Operand *OpFd, const Operand *OpFs); |
| 158 | |
| 159 | void c_ult_d(const Operand *OpFd, const Operand *OpFs); |
| 160 | |
| 161 | void c_ult_s(const Operand *OpFd, const Operand *OpFs); |
| 162 | |
| 163 | void c_un_d(const Operand *OpFd, const Operand *OpFs); |
| 164 | |
| 165 | void c_un_s(const Operand *OpFd, const Operand *OpFs); |
| 166 | |
Srdjan Obucina | d27ce3d | 2016-09-22 12:56:12 -0700 | [diff] [blame] | 167 | void clz(const Operand *OpRd, const Operand *OpRs); |
| 168 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 169 | void cvt_d_l(const Operand *OpFd, const Operand *OpFs); |
| 170 | |
| 171 | void cvt_d_s(const Operand *OpFd, const Operand *OpFs); |
| 172 | |
| 173 | void cvt_d_w(const Operand *OpFd, const Operand *OpFs); |
| 174 | |
| 175 | void cvt_s_d(const Operand *OpFd, const Operand *OpFs); |
| 176 | |
| 177 | void cvt_s_l(const Operand *OpFd, const Operand *OpFs); |
| 178 | |
| 179 | void cvt_s_w(const Operand *OpFd, const Operand *OpFs); |
| 180 | |
Srdjan Obucina | 623f8ce | 2016-09-26 20:03:20 -0700 | [diff] [blame] | 181 | void div(const Operand *OpRs, const Operand *OpRt); |
| 182 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 183 | void div_d(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt); |
| 184 | |
| 185 | void div_s(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt); |
| 186 | |
Srdjan Obucina | 6163c62 | 2016-09-27 20:38:30 -0700 | [diff] [blame] | 187 | void divu(const Operand *OpRs, const Operand *OpRt); |
| 188 | |
Jaydeep Patil | 130aca7 | 2016-10-28 05:30:54 -0700 | [diff] [blame] | 189 | void jal(const ConstantRelocatable *Target); |
| 190 | |
Jaydeep Patil | 0c4c07d | 2016-11-01 23:53:52 -0700 | [diff] [blame] | 191 | void jalr(const Operand *OpRs, const Operand *OpRd); |
| 192 | |
Jaydeep Patil | 130aca7 | 2016-10-28 05:30:54 -0700 | [diff] [blame] | 193 | void lui(const Operand *OpRt, const Operand *OpImm, const RelocOp Reloc); |
| 194 | |
| 195 | void ldc1(const Operand *OpRt, const Operand *OpBase, const Operand *OpOff, |
| 196 | const RelocOp Reloc); |
Srdjan Obucina | 623f8ce | 2016-09-26 20:03:20 -0700 | [diff] [blame] | 197 | |
Sagar Thakur | becb85f | 2016-11-18 12:15:46 -0800 | [diff] [blame] | 198 | void ll(const Operand *OpRt, const Operand *OpBase, const uint32_t Offset); |
| 199 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 200 | void lw(const Operand *OpRt, const Operand *OpBase, const uint32_t Offset); |
| 201 | |
Jaydeep Patil | 130aca7 | 2016-10-28 05:30:54 -0700 | [diff] [blame] | 202 | void lwc1(const Operand *OpRt, const Operand *OpBase, const Operand *OpOff, |
| 203 | const RelocOp Reloc); |
| 204 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 205 | void mfc1(const Operand *OpRt, const Operand *OpFs); |
| 206 | |
Srdjan Obucina | 623f8ce | 2016-09-26 20:03:20 -0700 | [diff] [blame] | 207 | void mfhi(const Operand *OpRd); |
| 208 | |
| 209 | void mflo(const Operand *OpRd); |
| 210 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 211 | void mov_d(const Operand *OpFd, const Operand *OpFs); |
| 212 | |
| 213 | void mov_s(const Operand *OpFd, const Operand *OpFs); |
| 214 | |
| 215 | void move(const Operand *OpRd, const Operand *OpRs); |
| 216 | |
Srdjan Obucina | 8d16c1d | 2016-09-20 08:44:44 -0700 | [diff] [blame] | 217 | void movf(const Operand *OpRd, const Operand *OpRs, const Operand *OpCc); |
| 218 | |
Srdjan Obucina | d27ce3d | 2016-09-22 12:56:12 -0700 | [diff] [blame] | 219 | void movn(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 220 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 221 | void movn_d(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt); |
| 222 | |
| 223 | void movn_s(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt); |
| 224 | |
Srdjan Obucina | 8d16c1d | 2016-09-20 08:44:44 -0700 | [diff] [blame] | 225 | void movt(const Operand *OpRd, const Operand *OpRs, const Operand *OpCc); |
| 226 | |
Srdjan Obucina | b0f09fc | 2016-09-27 20:43:11 -0700 | [diff] [blame] | 227 | void movz(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 228 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 229 | void movz_d(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt); |
| 230 | |
| 231 | void movz_s(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt); |
| 232 | |
| 233 | void mtc1(const Operand *OpRt, const Operand *OpFs); |
| 234 | |
Srdjan Obucina | 623f8ce | 2016-09-26 20:03:20 -0700 | [diff] [blame] | 235 | void mthi(const Operand *OpRs); |
| 236 | |
| 237 | void mtlo(const Operand *OpRs); |
| 238 | |
| 239 | void mul(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 240 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 241 | void mul_d(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt); |
| 242 | |
| 243 | void mul_s(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt); |
| 244 | |
Jaydeep Patil | 130aca7 | 2016-10-28 05:30:54 -0700 | [diff] [blame] | 245 | void mult(const Operand *OpRs, const Operand *OpRt); |
| 246 | |
Srdjan Obucina | 623f8ce | 2016-09-26 20:03:20 -0700 | [diff] [blame] | 247 | void multu(const Operand *OpRs, const Operand *OpRt); |
| 248 | |
Srdjan Obucina | cadda79 | 2016-09-22 11:24:44 -0700 | [diff] [blame] | 249 | void nor(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 250 | |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 251 | void or_(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 252 | |
| 253 | void ori(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| 254 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 255 | void ret(void); |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 256 | |
Sagar Thakur | becb85f | 2016-11-18 12:15:46 -0800 | [diff] [blame] | 257 | void sc(const Operand *OpRt, const Operand *OpBase, const uint32_t Offset); |
| 258 | |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 259 | void sll(const Operand *OpRd, const Operand *OpRt, const uint32_t Sa); |
| 260 | |
Srdjan Obucina | 623f8ce | 2016-09-26 20:03:20 -0700 | [diff] [blame] | 261 | void sllv(const Operand *OpRd, const Operand *OpRt, const Operand *OpRs); |
| 262 | |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 263 | void slt(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 264 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 265 | void slti(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| 266 | |
| 267 | void sltiu(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| 268 | |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 269 | void sltu(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 270 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 271 | void sqrt_d(const Operand *OpFd, const Operand *OpFs); |
| 272 | |
| 273 | void sqrt_s(const Operand *OpFd, const Operand *OpFs); |
| 274 | |
| 275 | void sra(const Operand *OpRd, const Operand *OpRt, const uint32_t Sa); |
| 276 | |
Srdjan Obucina | fe93fdd | 2016-09-28 06:38:44 -0700 | [diff] [blame] | 277 | void srav(const Operand *OpRd, const Operand *OpRt, const Operand *OpRs); |
| 278 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 279 | void srl(const Operand *OpRd, const Operand *OpRt, const uint32_t Sa); |
| 280 | |
Srdjan Obucina | 623f8ce | 2016-09-26 20:03:20 -0700 | [diff] [blame] | 281 | void srlv(const Operand *OpRd, const Operand *OpRt, const Operand *OpRs); |
| 282 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 283 | void sub_d(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt); |
| 284 | |
| 285 | void sub_s(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt); |
| 286 | |
Srdjan Obucina | 0a7f99d | 2016-09-23 06:59:50 -0700 | [diff] [blame] | 287 | void subu(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 288 | |
Jaydeep Patil | 130aca7 | 2016-10-28 05:30:54 -0700 | [diff] [blame] | 289 | void sdc1(const Operand *OpRt, const Operand *OpBase, const Operand *OpOff, |
| 290 | const RelocOp Reloc); |
| 291 | |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 292 | void sw(const Operand *OpRt, const Operand *OpBase, const uint32_t Offset); |
| 293 | |
Jaydeep Patil | 130aca7 | 2016-10-28 05:30:54 -0700 | [diff] [blame] | 294 | void swc1(const Operand *OpRt, const Operand *OpBase, const Operand *OpOff, |
| 295 | const RelocOp Reloc); |
| 296 | |
Sagar Thakur | becb85f | 2016-11-18 12:15:46 -0800 | [diff] [blame] | 297 | void sync(); |
| 298 | |
Srdjan Obucina | 3b61d70 | 2016-09-20 06:49:52 -0700 | [diff] [blame] | 299 | void teq(const Operand *OpRs, const Operand *OpRt, const uint32_t TrapCode); |
| 300 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 301 | void trunc_l_d(const Operand *OpFd, const Operand *OpFs); |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 302 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 303 | void trunc_l_s(const Operand *OpFd, const Operand *OpFs); |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 304 | |
Srdjan Obucina | 132ea7a | 2016-09-18 07:30:19 -0700 | [diff] [blame] | 305 | void trunc_w_d(const Operand *OpFd, const Operand *OpFs); |
| 306 | |
| 307 | void trunc_w_s(const Operand *OpFd, const Operand *OpFs); |
| 308 | |
| 309 | void xor_(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 310 | |
| 311 | void xori(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 312 | |
| 313 | void bcc(const CondMIPS32::Cond Cond, const Operand *OpRs, |
| 314 | const Operand *OpRt, Label *TargetLabel); |
| 315 | |
| 316 | void bzc(const CondMIPS32::Cond Cond, const Operand *OpRs, |
| 317 | Label *TargetLabel); |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 318 | |
| 319 | void alignFunction() override { |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 320 | const SizeT Align = 1 << getBundleAlignLog2Bytes(); |
| 321 | SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align); |
| 322 | constexpr SizeT InstSize = sizeof(IValueT); |
| 323 | assert(BytesNeeded % InstMIPS32::InstSize == 0); |
| 324 | while (BytesNeeded > 0) { |
| 325 | trap(); |
| 326 | BytesNeeded -= InstSize; |
| 327 | } |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 328 | } |
| 329 | |
| 330 | SizeT getBundleAlignLog2Bytes() const override { return 4; } |
| 331 | |
Andrew Scull | 86df4e9 | 2015-07-30 13:54:44 -0700 | [diff] [blame] | 332 | const char *getAlignDirective() const override { return ".p2alignl"; } |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 333 | |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 334 | llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override; |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 335 | |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 336 | void padWithNop(intptr_t Padding) override; |
| 337 | |
| 338 | void bind(Label *label); |
| 339 | |
| 340 | void emitTextInst(const std::string &Text, SizeT InstSize); |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 341 | |
Jan Voung | c2ec581 | 2015-08-05 09:35:18 -0700 | [diff] [blame] | 342 | Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override { |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 343 | assert(NodeNumber < CfgNodeLabels.size()); |
| 344 | return CfgNodeLabels[NodeNumber]; |
Andrew Scull | 86df4e9 | 2015-07-30 13:54:44 -0700 | [diff] [blame] | 345 | } |
| 346 | |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 347 | Label *getOrCreateCfgNodeLabel(SizeT NodeNumber) { |
| 348 | return getOrCreateLabel(NodeNumber, CfgNodeLabels); |
| 349 | } |
| 350 | |
| 351 | Label *getOrCreateLocalLabel(SizeT Number) { |
| 352 | return getOrCreateLabel(Number, LocalLabels); |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 353 | } |
| 354 | |
Jaydeep Patil | 58eeedf | 2016-09-26 20:48:18 -0700 | [diff] [blame] | 355 | void bindLocalLabel(const InstMIPS32Label *InstL, SizeT Number) { |
| 356 | if (BuildDefs::dump() && !getFlags().getDisableHybridAssembly()) { |
| 357 | constexpr SizeT InstSize = 0; |
| 358 | emitTextInst(InstL->getLabelName() + ":", InstSize); |
| 359 | } |
| 360 | Label *L = getOrCreateLocalLabel(Number); |
| 361 | if (!getPreliminary()) |
| 362 | this->bind(L); |
| 363 | } |
| 364 | |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 365 | bool fixupIsPCRel(FixupKind Kind) const override { |
| 366 | (void)Kind; |
Jaydeep Patil | 130aca7 | 2016-10-28 05:30:54 -0700 | [diff] [blame] | 367 | return false; |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 368 | } |
John Porto | 2da710c | 2015-06-29 07:57:02 -0700 | [diff] [blame] | 369 | |
| 370 | static bool classof(const Assembler *Asm) { |
| 371 | return Asm->getKind() == Asm_MIPS32; |
| 372 | } |
John Porto | 53611e2 | 2015-12-30 07:30:10 -0800 | [diff] [blame] | 373 | |
| 374 | private: |
| 375 | ENABLE_MAKE_UNIQUE; |
Jaydeep Patil | 135f5db | 2016-08-29 05:14:05 -0700 | [diff] [blame] | 376 | |
| 377 | using LabelVector = std::vector<Label *>; |
| 378 | LabelVector CfgNodeLabels; |
| 379 | LabelVector LocalLabels; |
| 380 | |
| 381 | // Returns the offset encoded in the branch instruction Inst. |
| 382 | static IOffsetT decodeBranchOffset(IValueT Inst); |
| 383 | |
| 384 | Label *getOrCreateLabel(SizeT Number, LabelVector &Labels); |
| 385 | |
| 386 | void bindCfgNodeLabel(const CfgNode *) override; |
| 387 | |
| 388 | void emitInst(IValueT Value) { |
| 389 | AssemblerBuffer::EnsureCapacity _(&Buffer); |
| 390 | Buffer.emit<IValueT>(Value); |
| 391 | } |
Jim Stichnoth | 6da4cef | 2015-06-11 13:26:33 -0700 | [diff] [blame] | 392 | }; |
| 393 | |
| 394 | } // end of namespace MIPS32 |
| 395 | } // end of namespace Ice |
| 396 | |
John Porto | 2da710c | 2015-06-29 07:57:02 -0700 | [diff] [blame] | 397 | #endif // SUBZERO_SRC_ICEASSEMBLERMIPS32_H |