/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file implements the MipsMCCodeEmitter class. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "MipsMCCodeEmitter.h" |
14 | | #include "MCTargetDesc/MipsFixupKinds.h" |
15 | | #include "MCTargetDesc/MipsMCExpr.h" |
16 | | #include "MCTargetDesc/MipsMCTargetDesc.h" |
17 | | #include "llvm/ADT/APFloat.h" |
18 | | #include "llvm/ADT/APInt.h" |
19 | | #include "llvm/ADT/SmallVector.h" |
20 | | #include "llvm/MC/MCContext.h" |
21 | | #include "llvm/MC/MCExpr.h" |
22 | | #include "llvm/MC/MCFixup.h" |
23 | | #include "llvm/MC/MCInst.h" |
24 | | #include "llvm/MC/MCInstrDesc.h" |
25 | | #include "llvm/MC/MCInstrInfo.h" |
26 | | #include "llvm/MC/MCRegisterInfo.h" |
27 | | #include "llvm/MC/MCSubtargetInfo.h" |
28 | | #include "llvm/Support/Casting.h" |
29 | | #include "llvm/Support/ErrorHandling.h" |
30 | | #include "llvm/Support/raw_ostream.h" |
31 | | #include <cassert> |
32 | | #include <cstdint> |
33 | | |
34 | | using namespace llvm; |
35 | | |
36 | | #define DEBUG_TYPE "mccodeemitter" |
37 | | |
38 | | #define GET_INSTRMAP_INFO |
39 | | #include "MipsGenInstrInfo.inc" |
40 | | #undef GET_INSTRMAP_INFO |
41 | | |
42 | | namespace llvm { |
43 | | |
44 | | MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, |
45 | | const MCRegisterInfo &MRI, |
46 | 690 | MCContext &Ctx) { |
47 | 690 | return new MipsMCCodeEmitter(MCII, Ctx, false); |
48 | 690 | } |
49 | | |
50 | | MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, |
51 | | const MCRegisterInfo &MRI, |
52 | 257 | MCContext &Ctx) { |
53 | 257 | return new MipsMCCodeEmitter(MCII, Ctx, true); |
54 | 257 | } |
55 | | |
56 | | } // end namespace llvm |
57 | | |
58 | | // If the D<shift> instruction has a shift amount that is greater |
59 | | // than 31 (checked in calling routine), lower it to a D<shift>32 instruction |
60 | 1.15k | static void LowerLargeShift(MCInst& Inst) { |
61 | 1.15k | assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!"); |
62 | 1.15k | assert(Inst.getOperand(2).isImm()); |
63 | 1.15k | |
64 | 1.15k | int64_t Shift = Inst.getOperand(2).getImm(); |
65 | 1.15k | if (Shift <= 31) |
66 | 1.12k | return; // Do nothing |
67 | 28 | Shift -= 32; |
68 | 28 | |
69 | 28 | // saminus32 |
70 | 28 | Inst.getOperand(2).setImm(Shift); |
71 | 28 | |
72 | 28 | switch (Inst.getOpcode()) { |
73 | 28 | default: |
74 | 0 | // Calling function is not synchronized |
75 | 0 | llvm_unreachable("Unexpected shift instruction"); |
76 | 28 | case Mips::DSLL: |
77 | 21 | Inst.setOpcode(Mips::DSLL32); |
78 | 21 | return; |
79 | 28 | case Mips::DSRL: |
80 | 5 | Inst.setOpcode(Mips::DSRL32); |
81 | 5 | return; |
82 | 28 | case Mips::DSRA: |
83 | 2 | Inst.setOpcode(Mips::DSRA32); |
84 | 2 | return; |
85 | 28 | case Mips::DROTR: |
86 | 0 | Inst.setOpcode(Mips::DROTR32); |
87 | 0 | return; |
88 | 28 | } |
89 | 28 | } |
90 | | |
91 | | // Fix a bad compact branch encoding for beqc/bnec. |
92 | 37 | void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const { |
93 | 37 | // Encoding may be illegal !(rs < rt), but this situation is |
94 | 37 | // easily fixed. |
95 | 37 | unsigned RegOp0 = Inst.getOperand(0).getReg(); |
96 | 37 | unsigned RegOp1 = Inst.getOperand(1).getReg(); |
97 | 37 | |
98 | 37 | unsigned Reg0 = Ctx.getRegisterInfo()->getEncodingValue(RegOp0); |
99 | 37 | unsigned Reg1 = Ctx.getRegisterInfo()->getEncodingValue(RegOp1); |
100 | 37 | |
101 | 37 | if (Inst.getOpcode() == Mips::BNEC || Inst.getOpcode() == Mips::BEQC27 || |
102 | 37 | Inst.getOpcode() == Mips::BNEC6417 || Inst.getOpcode() == Mips::BEQC6416 ) { |
103 | 21 | assert(Reg0 != Reg1 && "Instruction has bad operands ($rs == $rt)!"); |
104 | 21 | if (Reg0 < Reg1) |
105 | 14 | return; |
106 | 16 | } else if (Inst.getOpcode() == Mips::BNVC || Inst.getOpcode() == Mips::BOVC10 ) { |
107 | 12 | if (Reg0 >= Reg1) |
108 | 8 | return; |
109 | 4 | } else if (Inst.getOpcode() == Mips::BNVC_MMR6 || |
110 | 4 | Inst.getOpcode() == Mips::BOVC_MMR62 ) { |
111 | 4 | if (Reg1 >= Reg0) |
112 | 2 | return; |
113 | 4 | } else |
114 | 4 | llvm_unreachable("Cannot rewrite unknown branch!"); |
115 | 37 | |
116 | 37 | Inst.getOperand(0).setReg(RegOp1); |
117 | 13 | Inst.getOperand(1).setReg(RegOp0); |
118 | 13 | } |
119 | | |
120 | 59.5k | bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { |
121 | 59.5k | return STI.getFeatureBits()[Mips::FeatureMicroMips]; |
122 | 59.5k | } |
123 | | |
124 | 2.73k | bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const { |
125 | 2.73k | return STI.getFeatureBits()[Mips::FeatureMips32r6]; |
126 | 2.73k | } |
127 | | |
128 | 169k | void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { |
129 | 169k | OS << (char)C; |
130 | 169k | } |
131 | | |
132 | | void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, |
133 | | const MCSubtargetInfo &STI, |
134 | 44.1k | raw_ostream &OS) const { |
135 | 44.1k | // Output the instruction encoding in little endian byte order. |
136 | 44.1k | // Little-endian byte ordering: |
137 | 44.1k | // mips32r2: 4 | 3 | 2 | 1 |
138 | 44.1k | // microMIPS: 2 | 1 | 4 | 3 |
139 | 44.1k | if (IsLittleEndian && Size == 46.79k && isMicroMips(STI)5.16k ) { |
140 | 765 | EmitInstruction(Val >> 16, 2, STI, OS); |
141 | 765 | EmitInstruction(Val, 2, STI, OS); |
142 | 43.3k | } else { |
143 | 213k | for (unsigned i = 0; i < Size; ++i169k ) { |
144 | 169k | unsigned Shift = IsLittleEndian ? i * 820.8k : (Size - 1 - i) * 8148k ; |
145 | 169k | EmitByte((Val >> Shift) & 0xff, OS); |
146 | 169k | } |
147 | 43.3k | } |
148 | 44.1k | } |
149 | | |
150 | | /// encodeInstruction - Emit the instruction. |
151 | | /// Size the instruction with Desc.getSize(). |
152 | | void MipsMCCodeEmitter:: |
153 | | encodeInstruction(const MCInst &MI, raw_ostream &OS, |
154 | | SmallVectorImpl<MCFixup> &Fixups, |
155 | | const MCSubtargetInfo &STI) const |
156 | 42.6k | { |
157 | 42.6k | // Non-pseudo instructions that get changed for direct object |
158 | 42.6k | // only based on operand values. |
159 | 42.6k | // If this list of instructions get much longer we will move |
160 | 42.6k | // the check to a function call. Until then, this is more efficient. |
161 | 42.6k | MCInst TmpInst = MI; |
162 | 42.6k | switch (MI.getOpcode()) { |
163 | 42.6k | // If shift amount is >= 32 it the inst needs to be lowered further |
164 | 42.6k | case Mips::DSLL: |
165 | 1.15k | case Mips::DSRL: |
166 | 1.15k | case Mips::DSRA: |
167 | 1.15k | case Mips::DROTR: |
168 | 1.15k | LowerLargeShift(TmpInst); |
169 | 1.15k | break; |
170 | 1.15k | // Compact branches, enforce encoding restrictions. |
171 | 1.15k | case Mips::BEQC: |
172 | 37 | case Mips::BNEC: |
173 | 37 | case Mips::BEQC64: |
174 | 37 | case Mips::BNEC64: |
175 | 37 | case Mips::BOVC: |
176 | 37 | case Mips::BOVC_MMR6: |
177 | 37 | case Mips::BNVC: |
178 | 37 | case Mips::BNVC_MMR6: |
179 | 37 | LowerCompactBranch(TmpInst); |
180 | 42.6k | } |
181 | 42.6k | |
182 | 42.6k | unsigned long N = Fixups.size(); |
183 | 42.6k | uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); |
184 | 42.6k | |
185 | 42.6k | // Check for unimplemented opcodes. |
186 | 42.6k | // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0 |
187 | 42.6k | // so we have to special check for them. |
188 | 42.6k | const unsigned Opcode = TmpInst.getOpcode(); |
189 | 42.6k | if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && |
190 | 42.6k | (Opcode != Mips::SLL_MM)30.6k && (Opcode != Mips::SLL_MMR6)30.6k && !Binary30.6k ) |
191 | 42.6k | llvm_unreachable0 ("unimplemented opcode in encodeInstruction()"); |
192 | 42.6k | |
193 | 42.6k | int NewOpcode = -1; |
194 | 42.6k | if (isMicroMips(STI)) { |
195 | 2.73k | if (isMips32r6(STI)) { |
196 | 737 | NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6); |
197 | 737 | if (NewOpcode == -1) |
198 | 707 | NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6); |
199 | 737 | } |
200 | 1.99k | else |
201 | 1.99k | NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips); |
202 | 2.73k | |
203 | 2.73k | // Check whether it is Dsp instruction. |
204 | 2.73k | if (NewOpcode == -1) |
205 | 2.23k | NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp); |
206 | 2.73k | |
207 | 2.73k | if (NewOpcode != -1) { |
208 | 500 | if (Fixups.size() > N) |
209 | 52 | Fixups.pop_back(); |
210 | 500 | |
211 | 500 | TmpInst.setOpcode (NewOpcode); |
212 | 500 | Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); |
213 | 500 | } |
214 | 2.73k | |
215 | 2.73k | if (((MI.getOpcode() == Mips::MOVEP_MM) || |
216 | 2.73k | (MI.getOpcode() == Mips::MOVEP_MMR6)2.72k )) { |
217 | 4 | unsigned RegPair = getMovePRegPairOpValue(MI, 0, Fixups, STI); |
218 | 4 | Binary = (Binary & 0xFFFFFC7F) | (RegPair << 7); |
219 | 4 | } |
220 | 2.73k | } |
221 | 42.6k | |
222 | 42.6k | const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); |
223 | 42.6k | |
224 | 42.6k | // Get byte count of instruction |
225 | 42.6k | unsigned Size = Desc.getSize(); |
226 | 42.6k | if (!Size) |
227 | 42.6k | llvm_unreachable0 ("Desc.getSize() returns 0"); |
228 | 42.6k | |
229 | 42.6k | EmitInstruction(Binary, Size, STI, OS); |
230 | 42.6k | } |
231 | | |
232 | | /// getBranchTargetOpValue - Return binary encoding of the branch |
233 | | /// target operand. If the machine operand requires relocation, |
234 | | /// record the relocation and return zero. |
235 | | unsigned MipsMCCodeEmitter:: |
236 | | getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, |
237 | | SmallVectorImpl<MCFixup> &Fixups, |
238 | 740 | const MCSubtargetInfo &STI) const { |
239 | 740 | const MCOperand &MO = MI.getOperand(OpNo); |
240 | 740 | |
241 | 740 | // If the destination is an immediate, divide by 4. |
242 | 740 | if (MO.isImm()) return MO.getImm() >> 2432 ; |
243 | 308 | |
244 | 308 | assert(MO.isExpr() && |
245 | 308 | "getBranchTargetOpValue expects only expressions or immediates"); |
246 | 308 | |
247 | 308 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
248 | 308 | MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); |
249 | 308 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
250 | 308 | MCFixupKind(Mips::fixup_Mips_PC16))); |
251 | 308 | return 0; |
252 | 308 | } |
253 | | |
254 | | /// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch |
255 | | /// target operand. If the machine operand requires relocation, |
256 | | /// record the relocation and return zero. |
257 | | unsigned MipsMCCodeEmitter:: |
258 | | getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo, |
259 | | SmallVectorImpl<MCFixup> &Fixups, |
260 | 1 | const MCSubtargetInfo &STI) const { |
261 | 1 | const MCOperand &MO = MI.getOperand(OpNo); |
262 | 1 | |
263 | 1 | // If the destination is an immediate, divide by 2. |
264 | 1 | if (MO.isImm()) return MO.getImm() >> 1; |
265 | 0 | |
266 | 0 | assert(MO.isExpr() && |
267 | 0 | "getBranchTargetOpValue expects only expressions or immediates"); |
268 | 0 |
|
269 | 0 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
270 | 0 | MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); |
271 | 0 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
272 | 0 | MCFixupKind(Mips::fixup_Mips_PC16))); |
273 | 0 | return 0; |
274 | 0 | } |
275 | | |
276 | | /// getBranchTargetOpValueMMR6 - Return binary encoding of the branch |
277 | | /// target operand. If the machine operand requires relocation, |
278 | | /// record the relocation and return zero. |
279 | | unsigned MipsMCCodeEmitter:: |
280 | | getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo, |
281 | | SmallVectorImpl<MCFixup> &Fixups, |
282 | 4 | const MCSubtargetInfo &STI) const { |
283 | 4 | const MCOperand &MO = MI.getOperand(OpNo); |
284 | 4 | |
285 | 4 | // If the destination is an immediate, divide by 2. |
286 | 4 | if (MO.isImm()) |
287 | 4 | return MO.getImm() >> 1; |
288 | 0 | |
289 | 0 | assert(MO.isExpr() && |
290 | 0 | "getBranchTargetOpValueMMR6 expects only expressions or immediates"); |
291 | 0 |
|
292 | 0 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
293 | 0 | MO.getExpr(), MCConstantExpr::create(-2, Ctx), Ctx); |
294 | 0 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
295 | 0 | MCFixupKind(Mips::fixup_Mips_PC16))); |
296 | 0 | return 0; |
297 | 0 | } |
298 | | |
299 | | /// getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch |
300 | | /// target operand. If the machine operand requires relocation, |
301 | | /// record the relocation and return zero. |
302 | | unsigned MipsMCCodeEmitter:: |
303 | | getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo, |
304 | | SmallVectorImpl<MCFixup> &Fixups, |
305 | 10 | const MCSubtargetInfo &STI) const { |
306 | 10 | const MCOperand &MO = MI.getOperand(OpNo); |
307 | 10 | |
308 | 10 | // If the destination is an immediate, divide by 4. |
309 | 10 | if (MO.isImm()) |
310 | 10 | return MO.getImm() >> 2; |
311 | 0 | |
312 | 0 | assert(MO.isExpr() && |
313 | 0 | "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates"); |
314 | 0 |
|
315 | 0 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
316 | 0 | MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); |
317 | 0 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
318 | 0 | MCFixupKind(Mips::fixup_Mips_PC16))); |
319 | 0 | return 0; |
320 | 0 | } |
321 | | |
322 | | /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch |
323 | | /// target operand. If the machine operand requires relocation, |
324 | | /// record the relocation and return zero. |
325 | | unsigned MipsMCCodeEmitter:: |
326 | | getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, |
327 | | SmallVectorImpl<MCFixup> &Fixups, |
328 | 15 | const MCSubtargetInfo &STI) const { |
329 | 15 | const MCOperand &MO = MI.getOperand(OpNo); |
330 | 15 | |
331 | 15 | // If the destination is an immediate, divide by 2. |
332 | 15 | if (MO.isImm()) return MO.getImm() >> 19 ; |
333 | 6 | |
334 | 6 | assert(MO.isExpr() && |
335 | 6 | "getBranchTargetOpValueMM expects only expressions or immediates"); |
336 | 6 | |
337 | 6 | const MCExpr *Expr = MO.getExpr(); |
338 | 6 | Fixups.push_back(MCFixup::create(0, Expr, |
339 | 6 | MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1))); |
340 | 6 | return 0; |
341 | 6 | } |
342 | | |
343 | | /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS |
344 | | /// 10-bit branch target operand. If the machine operand requires relocation, |
345 | | /// record the relocation and return zero. |
346 | | unsigned MipsMCCodeEmitter:: |
347 | | getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo, |
348 | | SmallVectorImpl<MCFixup> &Fixups, |
349 | 13 | const MCSubtargetInfo &STI) const { |
350 | 13 | const MCOperand &MO = MI.getOperand(OpNo); |
351 | 13 | |
352 | 13 | // If the destination is an immediate, divide by 2. |
353 | 13 | if (MO.isImm()) return MO.getImm() >> 18 ; |
354 | 5 | |
355 | 5 | assert(MO.isExpr() && |
356 | 5 | "getBranchTargetOpValuePC10 expects only expressions or immediates"); |
357 | 5 | |
358 | 5 | const MCExpr *Expr = MO.getExpr(); |
359 | 5 | Fixups.push_back(MCFixup::create(0, Expr, |
360 | 5 | MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1))); |
361 | 5 | return 0; |
362 | 5 | } |
363 | | |
364 | | /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch |
365 | | /// target operand. If the machine operand requires relocation, |
366 | | /// record the relocation and return zero. |
367 | | unsigned MipsMCCodeEmitter:: |
368 | | getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, |
369 | | SmallVectorImpl<MCFixup> &Fixups, |
370 | 103 | const MCSubtargetInfo &STI) const { |
371 | 103 | const MCOperand &MO = MI.getOperand(OpNo); |
372 | 103 | |
373 | 103 | // If the destination is an immediate, divide by 2. |
374 | 103 | if (MO.isImm()) return MO.getImm() >> 156 ; |
375 | 47 | |
376 | 47 | assert(MO.isExpr() && |
377 | 47 | "getBranchTargetOpValueMM expects only expressions or immediates"); |
378 | 47 | |
379 | 47 | const MCExpr *Expr = MO.getExpr(); |
380 | 47 | Fixups.push_back(MCFixup::create(0, Expr, |
381 | 47 | MCFixupKind(Mips:: |
382 | 47 | fixup_MICROMIPS_PC16_S1))); |
383 | 47 | return 0; |
384 | 47 | } |
385 | | |
386 | | /// getBranchTarget21OpValue - Return binary encoding of the branch |
387 | | /// target operand. If the machine operand requires relocation, |
388 | | /// record the relocation and return zero. |
389 | | unsigned MipsMCCodeEmitter:: |
390 | | getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, |
391 | | SmallVectorImpl<MCFixup> &Fixups, |
392 | 26 | const MCSubtargetInfo &STI) const { |
393 | 26 | const MCOperand &MO = MI.getOperand(OpNo); |
394 | 26 | |
395 | 26 | // If the destination is an immediate, divide by 4. |
396 | 26 | if (MO.isImm()) return MO.getImm() >> 24 ; |
397 | 22 | |
398 | 22 | assert(MO.isExpr() && |
399 | 22 | "getBranchTarget21OpValue expects only expressions or immediates"); |
400 | 22 | |
401 | 22 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
402 | 22 | MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); |
403 | 22 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
404 | 22 | MCFixupKind(Mips::fixup_MIPS_PC21_S2))); |
405 | 22 | return 0; |
406 | 22 | } |
407 | | |
408 | | /// getBranchTarget21OpValueMM - Return binary encoding of the branch |
409 | | /// target operand for microMIPS. If the machine operand requires |
410 | | /// relocation, record the relocation and return zero. |
411 | | unsigned MipsMCCodeEmitter:: |
412 | | getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo, |
413 | | SmallVectorImpl<MCFixup> &Fixups, |
414 | 8 | const MCSubtargetInfo &STI) const { |
415 | 8 | const MCOperand &MO = MI.getOperand(OpNo); |
416 | 8 | |
417 | 8 | // If the destination is an immediate, divide by 4. |
418 | 8 | if (MO.isImm()) return MO.getImm() >> 22 ; |
419 | 6 | |
420 | 6 | assert(MO.isExpr() && |
421 | 6 | "getBranchTarget21OpValueMM expects only expressions or immediates"); |
422 | 6 | |
423 | 6 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
424 | 6 | MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); |
425 | 6 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
426 | 6 | MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1))); |
427 | 6 | return 0; |
428 | 6 | } |
429 | | |
430 | | /// getBranchTarget26OpValue - Return binary encoding of the branch |
431 | | /// target operand. If the machine operand requires relocation, |
432 | | /// record the relocation and return zero. |
433 | | unsigned MipsMCCodeEmitter:: |
434 | | getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, |
435 | | SmallVectorImpl<MCFixup> &Fixups, |
436 | 27 | const MCSubtargetInfo &STI) const { |
437 | 27 | const MCOperand &MO = MI.getOperand(OpNo); |
438 | 27 | |
439 | 27 | // If the destination is an immediate, divide by 4. |
440 | 27 | if (MO.isImm()) return MO.getImm() >> 26 ; |
441 | 21 | |
442 | 21 | assert(MO.isExpr() && |
443 | 21 | "getBranchTarget26OpValue expects only expressions or immediates"); |
444 | 21 | |
445 | 21 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
446 | 21 | MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); |
447 | 21 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
448 | 21 | MCFixupKind(Mips::fixup_MIPS_PC26_S2))); |
449 | 21 | return 0; |
450 | 21 | } |
451 | | |
452 | | /// getBranchTarget26OpValueMM - Return binary encoding of the branch |
453 | | /// target operand. If the machine operand requires relocation, |
454 | | /// record the relocation and return zero. |
455 | | unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM( |
456 | | const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, |
457 | 14 | const MCSubtargetInfo &STI) const { |
458 | 14 | const MCOperand &MO = MI.getOperand(OpNo); |
459 | 14 | |
460 | 14 | // If the destination is an immediate, divide by 2. |
461 | 14 | if (MO.isImm()) |
462 | 3 | return MO.getImm() >> 1; |
463 | 11 | |
464 | 11 | assert(MO.isExpr() && |
465 | 11 | "getBranchTarget26OpValueMM expects only expressions or immediates"); |
466 | 11 | |
467 | 11 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
468 | 11 | MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); |
469 | 11 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
470 | 11 | MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1))); |
471 | 11 | return 0; |
472 | 11 | } |
473 | | |
474 | | /// getJumpOffset16OpValue - Return binary encoding of the jump |
475 | | /// target operand. If the machine operand requires relocation, |
476 | | /// record the relocation and return zero. |
477 | | unsigned MipsMCCodeEmitter:: |
478 | | getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, |
479 | | SmallVectorImpl<MCFixup> &Fixups, |
480 | 52 | const MCSubtargetInfo &STI) const { |
481 | 52 | const MCOperand &MO = MI.getOperand(OpNo); |
482 | 52 | |
483 | 52 | if (MO.isImm()) return MO.getImm(); |
484 | 0 | |
485 | 0 | assert(MO.isExpr() && |
486 | 0 | "getJumpOffset16OpValue expects only expressions or an immediate"); |
487 | 0 |
|
488 | 0 | // TODO: Push fixup. |
489 | 0 | return 0; |
490 | 0 | } |
491 | | |
492 | | /// getJumpTargetOpValue - Return binary encoding of the jump |
493 | | /// target operand. If the machine operand requires relocation, |
494 | | /// record the relocation and return zero. |
495 | | unsigned MipsMCCodeEmitter:: |
496 | | getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, |
497 | | SmallVectorImpl<MCFixup> &Fixups, |
498 | 146 | const MCSubtargetInfo &STI) const { |
499 | 146 | const MCOperand &MO = MI.getOperand(OpNo); |
500 | 146 | // If the destination is an immediate, divide by 4. |
501 | 146 | if (MO.isImm()) return MO.getImm()>>241 ; |
502 | 105 | |
503 | 105 | assert(MO.isExpr() && |
504 | 105 | "getJumpTargetOpValue expects only expressions or an immediate"); |
505 | 105 | |
506 | 105 | const MCExpr *Expr = MO.getExpr(); |
507 | 105 | Fixups.push_back(MCFixup::create(0, Expr, |
508 | 105 | MCFixupKind(Mips::fixup_Mips_26))); |
509 | 105 | return 0; |
510 | 105 | } |
511 | | |
512 | | unsigned MipsMCCodeEmitter:: |
513 | | getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, |
514 | | SmallVectorImpl<MCFixup> &Fixups, |
515 | 37 | const MCSubtargetInfo &STI) const { |
516 | 37 | const MCOperand &MO = MI.getOperand(OpNo); |
517 | 37 | // If the destination is an immediate, divide by 2. |
518 | 37 | if (MO.isImm()) return MO.getImm() >> 19 ; |
519 | 28 | |
520 | 28 | assert(MO.isExpr() && |
521 | 28 | "getJumpTargetOpValueMM expects only expressions or an immediate"); |
522 | 28 | |
523 | 28 | const MCExpr *Expr = MO.getExpr(); |
524 | 28 | Fixups.push_back(MCFixup::create(0, Expr, |
525 | 28 | MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); |
526 | 28 | return 0; |
527 | 28 | } |
528 | | |
529 | | unsigned MipsMCCodeEmitter:: |
530 | | getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, |
531 | | SmallVectorImpl<MCFixup> &Fixups, |
532 | 4 | const MCSubtargetInfo &STI) const { |
533 | 4 | const MCOperand &MO = MI.getOperand(OpNo); |
534 | 4 | if (MO.isImm()) { |
535 | 4 | // The immediate is encoded as 'immediate << 2'. |
536 | 4 | unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); |
537 | 4 | assert((Res & 3) == 0); |
538 | 4 | return Res >> 2; |
539 | 4 | } |
540 | 0 | |
541 | 0 | assert(MO.isExpr() && |
542 | 0 | "getUImm5Lsl2Encoding expects only expressions or an immediate"); |
543 | 0 |
|
544 | 0 | return 0; |
545 | 0 | } |
546 | | |
547 | | unsigned MipsMCCodeEmitter:: |
548 | | getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, |
549 | | SmallVectorImpl<MCFixup> &Fixups, |
550 | 8 | const MCSubtargetInfo &STI) const { |
551 | 8 | const MCOperand &MO = MI.getOperand(OpNo); |
552 | 8 | if (MO.isImm()) { |
553 | 8 | int Value = MO.getImm(); |
554 | 8 | return Value >> 2; |
555 | 8 | } |
556 | 0 | |
557 | 0 | return 0; |
558 | 0 | } |
559 | | |
560 | | unsigned MipsMCCodeEmitter:: |
561 | | getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, |
562 | | SmallVectorImpl<MCFixup> &Fixups, |
563 | 4 | const MCSubtargetInfo &STI) const { |
564 | 4 | const MCOperand &MO = MI.getOperand(OpNo); |
565 | 4 | if (MO.isImm()) { |
566 | 4 | unsigned Value = MO.getImm(); |
567 | 4 | return Value >> 2; |
568 | 4 | } |
569 | 0 | |
570 | 0 | return 0; |
571 | 0 | } |
572 | | |
573 | | unsigned MipsMCCodeEmitter:: |
574 | | getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, |
575 | | SmallVectorImpl<MCFixup> &Fixups, |
576 | 26 | const MCSubtargetInfo &STI) const { |
577 | 26 | const MCOperand &MO = MI.getOperand(OpNo); |
578 | 26 | if (MO.isImm()) { |
579 | 26 | unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff; |
580 | 26 | return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff)); |
581 | 26 | } |
582 | 0 | |
583 | 0 | return 0; |
584 | 0 | } |
585 | | |
586 | | unsigned MipsMCCodeEmitter:: |
587 | | getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, |
588 | 11.7k | const MCSubtargetInfo &STI) const { |
589 | 11.7k | int64_t Res; |
590 | 11.7k | |
591 | 11.7k | if (Expr->evaluateAsAbsolute(Res)) |
592 | 18 | return Res; |
593 | 11.7k | |
594 | 11.7k | MCExpr::ExprKind Kind = Expr->getKind(); |
595 | 11.7k | if (Kind == MCExpr::Constant) { |
596 | 0 | return cast<MCConstantExpr>(Expr)->getValue(); |
597 | 0 | } |
598 | 11.7k | |
599 | 11.7k | if (Kind == MCExpr::Binary) { |
600 | 0 | unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); |
601 | 0 | Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); |
602 | 0 | return Res; |
603 | 0 | } |
604 | 11.7k | |
605 | 11.7k | if (Kind == MCExpr::Target) { |
606 | 11.7k | const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); |
607 | 11.7k | |
608 | 11.7k | Mips::Fixups FixupKind = Mips::Fixups(0); |
609 | 11.7k | switch (MipsExpr->getKind()) { |
610 | 11.7k | case MipsMCExpr::MEK_None: |
611 | 0 | case MipsMCExpr::MEK_Special: |
612 | 0 | llvm_unreachable("Unhandled fixup kind!"); |
613 | 0 | break; |
614 | 0 | case MipsMCExpr::MEK_DTPREL: |
615 | 0 | // MEK_DTPREL is used for marking TLS DIEExpr only |
616 | 0 | // and contains a regular sub-expression. |
617 | 0 | return getExprOpValue(MipsExpr->getSubExpr(), Fixups, STI); |
618 | 8 | case MipsMCExpr::MEK_CALL_HI16: |
619 | 8 | FixupKind = Mips::fixup_Mips_CALL_HI16; |
620 | 8 | break; |
621 | 8 | case MipsMCExpr::MEK_CALL_LO16: |
622 | 8 | FixupKind = Mips::fixup_Mips_CALL_LO16; |
623 | 8 | break; |
624 | 10 | case MipsMCExpr::MEK_DTPREL_HI: |
625 | 10 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI162 |
626 | 10 | : Mips::fixup_Mips_DTPREL_HI8 ; |
627 | 10 | break; |
628 | 11 | case MipsMCExpr::MEK_DTPREL_LO: |
629 | 11 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO162 |
630 | 11 | : Mips::fixup_Mips_DTPREL_LO9 ; |
631 | 11 | break; |
632 | 19 | case MipsMCExpr::MEK_GOTTPREL: |
633 | 19 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOTTPREL4 |
634 | 19 | : Mips::fixup_Mips_GOTTPREL15 ; |
635 | 19 | break; |
636 | 213 | case MipsMCExpr::MEK_GOT: |
637 | 213 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT1639 |
638 | 213 | : Mips::fixup_Mips_GOT174 ; |
639 | 213 | break; |
640 | 10.0k | case MipsMCExpr::MEK_GOT_CALL: |
641 | 10.0k | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL1619 |
642 | 10.0k | : Mips::fixup_Mips_CALL1610.0k ; |
643 | 10.0k | break; |
644 | 52 | case MipsMCExpr::MEK_GOT_DISP: |
645 | 52 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP2 |
646 | 52 | : Mips::fixup_Mips_GOT_DISP50 ; |
647 | 52 | break; |
648 | 10 | case MipsMCExpr::MEK_GOT_HI16: |
649 | 10 | FixupKind = Mips::fixup_Mips_GOT_HI16; |
650 | 10 | break; |
651 | 10 | case MipsMCExpr::MEK_GOT_LO16: |
652 | 10 | FixupKind = Mips::fixup_Mips_GOT_LO16; |
653 | 10 | break; |
654 | 38 | case MipsMCExpr::MEK_GOT_PAGE: |
655 | 38 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE6 |
656 | 38 | : Mips::fixup_Mips_GOT_PAGE32 ; |
657 | 38 | break; |
658 | 28 | case MipsMCExpr::MEK_GOT_OFST: |
659 | 28 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST6 |
660 | 28 | : Mips::fixup_Mips_GOT_OFST22 ; |
661 | 28 | break; |
662 | 12 | case MipsMCExpr::MEK_GPREL: |
663 | 12 | FixupKind = Mips::fixup_Mips_GPREL16; |
664 | 12 | break; |
665 | 752 | case MipsMCExpr::MEK_LO: |
666 | 752 | // Check for %lo(%neg(%gp_rel(X))) |
667 | 752 | if (MipsExpr->isGpOff()) |
668 | 38 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_LO8 |
669 | 38 | : Mips::fixup_Mips_GPOFF_LO30 ; |
670 | 714 | else |
671 | 714 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO1679 |
672 | 714 | : Mips::fixup_Mips_LO16635 ; |
673 | 752 | break; |
674 | 56 | case MipsMCExpr::MEK_HIGHEST: |
675 | 56 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHEST4 |
676 | 56 | : Mips::fixup_Mips_HIGHEST52 ; |
677 | 56 | break; |
678 | 56 | case MipsMCExpr::MEK_HIGHER: |
679 | 56 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHER4 |
680 | 56 | : Mips::fixup_Mips_HIGHER52 ; |
681 | 56 | break; |
682 | 340 | case MipsMCExpr::MEK_HI: |
683 | 340 | // Check for %hi(%neg(%gp_rel(X))) |
684 | 340 | if (MipsExpr->isGpOff()) |
685 | 40 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_HI8 |
686 | 40 | : Mips::fixup_Mips_GPOFF_HI32 ; |
687 | 300 | else |
688 | 300 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI1649 |
689 | 300 | : Mips::fixup_Mips_HI16251 ; |
690 | 340 | break; |
691 | 13 | case MipsMCExpr::MEK_PCREL_HI16: |
692 | 13 | FixupKind = Mips::fixup_MIPS_PCHI16; |
693 | 13 | break; |
694 | 13 | case MipsMCExpr::MEK_PCREL_LO16: |
695 | 13 | FixupKind = Mips::fixup_MIPS_PCLO16; |
696 | 13 | break; |
697 | 18 | case MipsMCExpr::MEK_TLSGD: |
698 | 18 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD2 |
699 | 18 | : Mips::fixup_Mips_TLSGD16 ; |
700 | 18 | break; |
701 | 11 | case MipsMCExpr::MEK_TLSLDM: |
702 | 11 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM2 |
703 | 11 | : Mips::fixup_Mips_TLSLDM9 ; |
704 | 11 | break; |
705 | 9 | case MipsMCExpr::MEK_TPREL_HI: |
706 | 9 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI162 |
707 | 9 | : Mips::fixup_Mips_TPREL_HI7 ; |
708 | 9 | break; |
709 | 9 | case MipsMCExpr::MEK_TPREL_LO: |
710 | 9 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO162 |
711 | 9 | : Mips::fixup_Mips_TPREL_LO7 ; |
712 | 9 | break; |
713 | 0 | case MipsMCExpr::MEK_NEG: |
714 | 0 | FixupKind = |
715 | 0 | isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB; |
716 | 0 | break; |
717 | 11.7k | } |
718 | 11.7k | Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); |
719 | 11.7k | return 0; |
720 | 11.7k | } |
721 | 0 | |
722 | 0 | if (Kind == MCExpr::SymbolRef) { |
723 | 0 | Mips::Fixups FixupKind = Mips::Fixups(0); |
724 | 0 |
|
725 | 0 | switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { |
726 | 0 | default: llvm_unreachable("Unknown fixup kind!"); |
727 | 0 | break; |
728 | 0 | case MCSymbolRefExpr::VK_None: |
729 | 0 | FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. |
730 | 0 | break; |
731 | 0 | } // switch |
732 | 0 | |
733 | 0 | Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); |
734 | 0 | return 0; |
735 | 0 | } |
736 | 0 | return 0; |
737 | 0 | } |
738 | | |
739 | | /// getMachineOpValue - Return binary encoding of operand. If the machine |
740 | | /// operand requires relocation, record the relocation and return zero. |
741 | | unsigned MipsMCCodeEmitter:: |
742 | | getMachineOpValue(const MCInst &MI, const MCOperand &MO, |
743 | | SmallVectorImpl<MCFixup> &Fixups, |
744 | 120k | const MCSubtargetInfo &STI) const { |
745 | 120k | if (MO.isReg()) { |
746 | 85.5k | unsigned Reg = MO.getReg(); |
747 | 85.5k | unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); |
748 | 85.5k | return RegNo; |
749 | 85.5k | } else if (34.8k MO.isImm()34.8k ) { |
750 | 23.0k | return static_cast<unsigned>(MO.getImm()); |
751 | 23.0k | } else if (11.7k MO.isFPImm()11.7k ) { |
752 | 0 | return static_cast<unsigned>(APFloat(MO.getFPImm()) |
753 | 0 | .bitcastToAPInt().getHiBits(32).getLimitedValue()); |
754 | 0 | } |
755 | 11.7k | // MO must be an Expr. |
756 | 11.7k | assert(MO.isExpr()); |
757 | 11.7k | return getExprOpValue(MO.getExpr(),Fixups, STI); |
758 | 11.7k | } |
759 | | |
760 | | /// Return binary encoding of memory related operand. |
761 | | /// If the offset operand requires relocation, record the relocation. |
762 | | template <unsigned ShiftAmount> |
763 | | unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, |
764 | | SmallVectorImpl<MCFixup> &Fixups, |
765 | 12.7k | const MCSubtargetInfo &STI) const { |
766 | 12.7k | // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. |
767 | 12.7k | assert(MI.getOperand(OpNo).isReg()); |
768 | 12.7k | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; |
769 | 12.7k | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); |
770 | 12.7k | |
771 | 12.7k | // Apply the scale factor if there is one. |
772 | 12.7k | OffBits >>= ShiftAmount; |
773 | 12.7k | |
774 | 12.7k | return (OffBits & 0xFFFF) | RegBits; |
775 | 12.7k | } unsigned int llvm::MipsMCCodeEmitter::getMemEncoding<0u>(llvm::MCInst const&, unsigned int, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const Line | Count | Source | 765 | 12.6k | const MCSubtargetInfo &STI) const { | 766 | 12.6k | // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. | 767 | 12.6k | assert(MI.getOperand(OpNo).isReg()); | 768 | 12.6k | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; | 769 | 12.6k | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); | 770 | 12.6k | | 771 | 12.6k | // Apply the scale factor if there is one. | 772 | 12.6k | OffBits >>= ShiftAmount; | 773 | 12.6k | | 774 | 12.6k | return (OffBits & 0xFFFF) | RegBits; | 775 | 12.6k | } |
unsigned int llvm::MipsMCCodeEmitter::getMemEncoding<1u>(llvm::MCInst const&, unsigned int, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const Line | Count | Source | 765 | 5 | const MCSubtargetInfo &STI) const { | 766 | 5 | // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. | 767 | 5 | assert(MI.getOperand(OpNo).isReg()); | 768 | 5 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; | 769 | 5 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); | 770 | 5 | | 771 | 5 | // Apply the scale factor if there is one. | 772 | 5 | OffBits >>= ShiftAmount; | 773 | 5 | | 774 | 5 | return (OffBits & 0xFFFF) | RegBits; | 775 | 5 | } |
unsigned int llvm::MipsMCCodeEmitter::getMemEncoding<2u>(llvm::MCInst const&, unsigned int, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const Line | Count | Source | 765 | 6 | const MCSubtargetInfo &STI) const { | 766 | 6 | // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. | 767 | 6 | assert(MI.getOperand(OpNo).isReg()); | 768 | 6 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; | 769 | 6 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); | 770 | 6 | | 771 | 6 | // Apply the scale factor if there is one. | 772 | 6 | OffBits >>= ShiftAmount; | 773 | 6 | | 774 | 6 | return (OffBits & 0xFFFF) | RegBits; | 775 | 6 | } |
unsigned int llvm::MipsMCCodeEmitter::getMemEncoding<3u>(llvm::MCInst const&, unsigned int, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const Line | Count | Source | 765 | 9 | const MCSubtargetInfo &STI) const { | 766 | 9 | // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. | 767 | 9 | assert(MI.getOperand(OpNo).isReg()); | 768 | 9 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; | 769 | 9 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); | 770 | 9 | | 771 | 9 | // Apply the scale factor if there is one. | 772 | 9 | OffBits >>= ShiftAmount; | 773 | 9 | | 774 | 9 | return (OffBits & 0xFFFF) | RegBits; | 775 | 9 | } |
|
776 | | |
777 | | unsigned MipsMCCodeEmitter:: |
778 | | getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, |
779 | | SmallVectorImpl<MCFixup> &Fixups, |
780 | 12 | const MCSubtargetInfo &STI) const { |
781 | 12 | // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. |
782 | 12 | assert(MI.getOperand(OpNo).isReg()); |
783 | 12 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), |
784 | 12 | Fixups, STI) << 4; |
785 | 12 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), |
786 | 12 | Fixups, STI); |
787 | 12 | |
788 | 12 | return (OffBits & 0xF) | RegBits; |
789 | 12 | } |
790 | | |
791 | | unsigned MipsMCCodeEmitter:: |
792 | | getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, |
793 | | SmallVectorImpl<MCFixup> &Fixups, |
794 | 8 | const MCSubtargetInfo &STI) const { |
795 | 8 | // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. |
796 | 8 | assert(MI.getOperand(OpNo).isReg()); |
797 | 8 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), |
798 | 8 | Fixups, STI) << 4; |
799 | 8 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), |
800 | 8 | Fixups, STI) >> 1; |
801 | 8 | |
802 | 8 | return (OffBits & 0xF) | RegBits; |
803 | 8 | } |
804 | | |
805 | | unsigned MipsMCCodeEmitter:: |
806 | | getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, |
807 | | SmallVectorImpl<MCFixup> &Fixups, |
808 | 18 | const MCSubtargetInfo &STI) const { |
809 | 18 | // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. |
810 | 18 | assert(MI.getOperand(OpNo).isReg()); |
811 | 18 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), |
812 | 18 | Fixups, STI) << 4; |
813 | 18 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), |
814 | 18 | Fixups, STI) >> 2; |
815 | 18 | |
816 | 18 | return (OffBits & 0xF) | RegBits; |
817 | 18 | } |
818 | | |
819 | | unsigned MipsMCCodeEmitter:: |
820 | | getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, |
821 | | SmallVectorImpl<MCFixup> &Fixups, |
822 | 23 | const MCSubtargetInfo &STI) const { |
823 | 23 | // Register is encoded in bits 9-5, offset is encoded in bits 4-0. |
824 | 23 | assert(MI.getOperand(OpNo).isReg() && |
825 | 23 | (MI.getOperand(OpNo).getReg() == Mips::SP || |
826 | 23 | MI.getOperand(OpNo).getReg() == Mips::SP_64) && |
827 | 23 | "Unexpected base register!"); |
828 | 23 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), |
829 | 23 | Fixups, STI) >> 2; |
830 | 23 | |
831 | 23 | return OffBits & 0x1F; |
832 | 23 | } |
833 | | |
834 | | unsigned MipsMCCodeEmitter:: |
835 | | getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, |
836 | | SmallVectorImpl<MCFixup> &Fixups, |
837 | 6 | const MCSubtargetInfo &STI) const { |
838 | 6 | // Register is encoded in bits 9-7, offset is encoded in bits 6-0. |
839 | 6 | assert(MI.getOperand(OpNo).isReg() && |
840 | 6 | MI.getOperand(OpNo).getReg() == Mips::GP && |
841 | 6 | "Unexpected base register!"); |
842 | 6 | |
843 | 6 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), |
844 | 6 | Fixups, STI) >> 2; |
845 | 6 | |
846 | 6 | return OffBits & 0x7F; |
847 | 6 | } |
848 | | |
849 | | unsigned MipsMCCodeEmitter:: |
850 | | getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, |
851 | | SmallVectorImpl<MCFixup> &Fixups, |
852 | 30 | const MCSubtargetInfo &STI) const { |
853 | 30 | // Base register is encoded in bits 20-16, offset is encoded in bits 8-0. |
854 | 30 | assert(MI.getOperand(OpNo).isReg()); |
855 | 30 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, |
856 | 30 | STI) << 16; |
857 | 30 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI); |
858 | 30 | |
859 | 30 | return (OffBits & 0x1FF) | RegBits; |
860 | 30 | } |
861 | | |
862 | | unsigned MipsMCCodeEmitter:: |
863 | | getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo, |
864 | | SmallVectorImpl<MCFixup> &Fixups, |
865 | 4 | const MCSubtargetInfo &STI) const { |
866 | 4 | // Base register is encoded in bits 20-16, offset is encoded in bits 10-0. |
867 | 4 | assert(MI.getOperand(OpNo).isReg()); |
868 | 4 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, |
869 | 4 | STI) << 16; |
870 | 4 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); |
871 | 4 | |
872 | 4 | return (OffBits & 0x07FF) | RegBits; |
873 | 4 | } |
874 | | |
875 | | unsigned MipsMCCodeEmitter:: |
876 | | getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, |
877 | | SmallVectorImpl<MCFixup> &Fixups, |
878 | 79 | const MCSubtargetInfo &STI) const { |
879 | 79 | // opNum can be invalid if instruction had reglist as operand. |
880 | 79 | // MemOperand is always last operand of instruction (base + offset). |
881 | 79 | switch (MI.getOpcode()) { |
882 | 79 | default: |
883 | 34 | break; |
884 | 79 | case Mips::SWM32_MM: |
885 | 45 | case Mips::LWM32_MM: |
886 | 45 | OpNo = MI.getNumOperands() - 2; |
887 | 45 | break; |
888 | 79 | } |
889 | 79 | |
890 | 79 | // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. |
891 | 79 | assert(MI.getOperand(OpNo).isReg()); |
892 | 79 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; |
893 | 79 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); |
894 | 79 | |
895 | 79 | return (OffBits & 0x0FFF) | RegBits; |
896 | 79 | } |
897 | | |
898 | | unsigned MipsMCCodeEmitter:: |
899 | | getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, |
900 | | SmallVectorImpl<MCFixup> &Fixups, |
901 | 40 | const MCSubtargetInfo &STI) const { |
902 | 40 | // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. |
903 | 40 | assert(MI.getOperand(OpNo).isReg()); |
904 | 40 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, |
905 | 40 | STI) << 16; |
906 | 40 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); |
907 | 40 | |
908 | 40 | return (OffBits & 0xFFFF) | RegBits; |
909 | 40 | } |
910 | | |
911 | | unsigned MipsMCCodeEmitter:: |
912 | | getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, |
913 | | SmallVectorImpl<MCFixup> &Fixups, |
914 | 14 | const MCSubtargetInfo &STI) const { |
915 | 14 | // opNum can be invalid if instruction had reglist as operand |
916 | 14 | // MemOperand is always last operand of instruction (base + offset) |
917 | 14 | switch (MI.getOpcode()) { |
918 | 14 | default: |
919 | 0 | break; |
920 | 14 | case Mips::SWM16_MM: |
921 | 14 | case Mips::SWM16_MMR6: |
922 | 14 | case Mips::LWM16_MM: |
923 | 14 | case Mips::LWM16_MMR6: |
924 | 14 | OpNo = MI.getNumOperands() - 2; |
925 | 14 | break; |
926 | 14 | } |
927 | 14 | |
928 | 14 | // Offset is encoded in bits 4-0. |
929 | 14 | assert(MI.getOperand(OpNo).isReg()); |
930 | 14 | // Base register is always SP - thus it is not encoded. |
931 | 14 | assert(MI.getOperand(OpNo+1).isImm()); |
932 | 14 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); |
933 | 14 | |
934 | 14 | return ((OffBits >> 2) & 0x0F); |
935 | 14 | } |
936 | | |
937 | | // FIXME: should be called getMSBEncoding |
938 | | // |
939 | | unsigned |
940 | | MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, |
941 | | SmallVectorImpl<MCFixup> &Fixups, |
942 | 19 | const MCSubtargetInfo &STI) const { |
943 | 19 | assert(MI.getOperand(OpNo-1).isImm()); |
944 | 19 | assert(MI.getOperand(OpNo).isImm()); |
945 | 19 | unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); |
946 | 19 | unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); |
947 | 19 | |
948 | 19 | return Position + Size - 1; |
949 | 19 | } |
950 | | |
951 | | template <unsigned Bits, int Offset> |
952 | | unsigned |
953 | | MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, |
954 | | SmallVectorImpl<MCFixup> &Fixups, |
955 | 30 | const MCSubtargetInfo &STI) const { |
956 | 30 | assert(MI.getOperand(OpNo).isImm()); |
957 | 30 | unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); |
958 | 30 | Value -= Offset; |
959 | 30 | return Value; |
960 | 30 | } unsigned int llvm::MipsMCCodeEmitter::getUImmWithOffsetEncoding<2u, 1>(llvm::MCInst const&, unsigned int, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const Line | Count | Source | 955 | 12 | const MCSubtargetInfo &STI) const { | 956 | 12 | assert(MI.getOperand(OpNo).isImm()); | 957 | 12 | unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); | 958 | 12 | Value -= Offset; | 959 | 12 | return Value; | 960 | 12 | } |
unsigned int llvm::MipsMCCodeEmitter::getUImmWithOffsetEncoding<5u, 1>(llvm::MCInst const&, unsigned int, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const Line | Count | Source | 955 | 18 | const MCSubtargetInfo &STI) const { | 956 | 18 | assert(MI.getOperand(OpNo).isImm()); | 957 | 18 | unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); | 958 | 18 | Value -= Offset; | 959 | 18 | return Value; | 960 | 18 | } |
|
961 | | |
962 | | unsigned |
963 | | MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, |
964 | | SmallVectorImpl<MCFixup> &Fixups, |
965 | 56 | const MCSubtargetInfo &STI) const { |
966 | 56 | const MCOperand &MO = MI.getOperand(OpNo); |
967 | 56 | if (MO.isImm()) { |
968 | 17 | // The immediate is encoded as 'immediate << 2'. |
969 | 17 | unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); |
970 | 17 | assert((Res & 3) == 0); |
971 | 17 | return Res >> 2; |
972 | 17 | } |
973 | 39 | |
974 | 39 | assert(MO.isExpr() && |
975 | 39 | "getSimm19Lsl2Encoding expects only expressions or an immediate"); |
976 | 39 | |
977 | 39 | const MCExpr *Expr = MO.getExpr(); |
978 | 39 | Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S216 |
979 | 39 | : Mips::fixup_MIPS_PC19_S223 ; |
980 | 39 | Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); |
981 | 39 | return 0; |
982 | 39 | } |
983 | | |
984 | | unsigned |
985 | | MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, |
986 | | SmallVectorImpl<MCFixup> &Fixups, |
987 | 9 | const MCSubtargetInfo &STI) const { |
988 | 9 | const MCOperand &MO = MI.getOperand(OpNo); |
989 | 9 | if (MO.isImm()) { |
990 | 1 | // The immediate is encoded as 'immediate << 3'. |
991 | 1 | unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); |
992 | 1 | assert((Res & 7) == 0); |
993 | 1 | return Res >> 3; |
994 | 1 | } |
995 | 8 | |
996 | 8 | assert(MO.isExpr() && |
997 | 8 | "getSimm18Lsl2Encoding expects only expressions or an immediate"); |
998 | 8 | |
999 | 8 | const MCExpr *Expr = MO.getExpr(); |
1000 | 8 | Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S30 |
1001 | 8 | : Mips::fixup_MIPS_PC18_S3; |
1002 | 8 | Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); |
1003 | 8 | return 0; |
1004 | 8 | } |
1005 | | |
1006 | | unsigned |
1007 | | MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, |
1008 | | SmallVectorImpl<MCFixup> &Fixups, |
1009 | 8 | const MCSubtargetInfo &STI) const { |
1010 | 8 | assert(MI.getOperand(OpNo).isImm()); |
1011 | 8 | const MCOperand &MO = MI.getOperand(OpNo); |
1012 | 8 | return MO.getImm() % 8; |
1013 | 8 | } |
1014 | | |
1015 | | unsigned |
1016 | | MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, |
1017 | | SmallVectorImpl<MCFixup> &Fixups, |
1018 | 5 | const MCSubtargetInfo &STI) const { |
1019 | 5 | assert(MI.getOperand(OpNo).isImm()); |
1020 | 5 | const MCOperand &MO = MI.getOperand(OpNo); |
1021 | 5 | unsigned Value = MO.getImm(); |
1022 | 5 | switch (Value) { |
1023 | 5 | case 128: return 0x00 ; |
1024 | 5 | case 1: return 0x11 ; |
1025 | 5 | case 2: return 0x20 ; |
1026 | 5 | case 3: return 0x30 ; |
1027 | 5 | case 4: return 0x40 ; |
1028 | 5 | case 7: return 0x50 ; |
1029 | 5 | case 8: return 0x61 ; |
1030 | 5 | case 15: return 0x70 ; |
1031 | 5 | case 16: return 0x80 ; |
1032 | 5 | case 31: return 0x93 ; |
1033 | 5 | case 32: return 0xa0 ; |
1034 | 5 | case 63: return 0xb0 ; |
1035 | 5 | case 64: return 0xc0 ; |
1036 | 5 | case 255: return 0xd0 ; |
1037 | 5 | case 32768: return 0xe0 ; |
1038 | 5 | case 65535: return 0xf0 ; |
1039 | 0 | } |
1040 | 0 | llvm_unreachable("Unexpected value"); |
1041 | 0 | } |
1042 | | |
1043 | | unsigned |
1044 | | MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, |
1045 | | SmallVectorImpl<MCFixup> &Fixups, |
1046 | 45 | const MCSubtargetInfo &STI) const { |
1047 | 45 | unsigned res = 0; |
1048 | 45 | |
1049 | 45 | // Register list operand is always first operand of instruction and it is |
1050 | 45 | // placed before memory operand (register + imm). |
1051 | 45 | |
1052 | 244 | for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I199 ) { |
1053 | 199 | unsigned Reg = MI.getOperand(I).getReg(); |
1054 | 199 | unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); |
1055 | 199 | if (RegNo != 31) |
1056 | 178 | res++; |
1057 | 21 | else |
1058 | 21 | res |= 0x10; |
1059 | 199 | } |
1060 | 45 | return res; |
1061 | 45 | } |
1062 | | |
1063 | | unsigned |
1064 | | MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, |
1065 | | SmallVectorImpl<MCFixup> &Fixups, |
1066 | 14 | const MCSubtargetInfo &STI) const { |
1067 | 14 | return (MI.getNumOperands() - 4); |
1068 | 14 | } |
1069 | | |
1070 | | unsigned |
1071 | | MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, |
1072 | | SmallVectorImpl<MCFixup> &Fixups, |
1073 | 4 | const MCSubtargetInfo &STI) const { |
1074 | 4 | unsigned res = 0; |
1075 | 4 | |
1076 | 4 | if (MI.getOperand(0).getReg() == Mips::A1 && |
1077 | 4 | MI.getOperand(1).getReg() == Mips::A2) |
1078 | 4 | res = 0; |
1079 | 0 | else if (MI.getOperand(0).getReg() == Mips::A1 && |
1080 | 0 | MI.getOperand(1).getReg() == Mips::A3) |
1081 | 0 | res = 1; |
1082 | 0 | else if (MI.getOperand(0).getReg() == Mips::A2 && |
1083 | 0 | MI.getOperand(1).getReg() == Mips::A3) |
1084 | 0 | res = 2; |
1085 | 0 | else if (MI.getOperand(0).getReg() == Mips::A0 && |
1086 | 0 | MI.getOperand(1).getReg() == Mips::S5) |
1087 | 0 | res = 3; |
1088 | 0 | else if (MI.getOperand(0).getReg() == Mips::A0 && |
1089 | 0 | MI.getOperand(1).getReg() == Mips::S6) |
1090 | 0 | res = 4; |
1091 | 0 | else if (MI.getOperand(0).getReg() == Mips::A0 && |
1092 | 0 | MI.getOperand(1).getReg() == Mips::A1) |
1093 | 0 | res = 5; |
1094 | 0 | else if (MI.getOperand(0).getReg() == Mips::A0 && |
1095 | 0 | MI.getOperand(1).getReg() == Mips::A2) |
1096 | 0 | res = 6; |
1097 | 0 | else if (MI.getOperand(0).getReg() == Mips::A0 && |
1098 | 0 | MI.getOperand(1).getReg() == Mips::A3) |
1099 | 0 | res = 7; |
1100 | 4 | |
1101 | 4 | return res; |
1102 | 4 | } |
1103 | | |
1104 | | unsigned |
1105 | | MipsMCCodeEmitter::getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo, |
1106 | | SmallVectorImpl<MCFixup> &Fixups, |
1107 | 8 | const MCSubtargetInfo &STI) const { |
1108 | 8 | assert(((OpNo == 2) || (OpNo == 3)) && |
1109 | 8 | "Unexpected OpNo for movep operand encoding!"); |
1110 | 8 | |
1111 | 8 | MCOperand Op = MI.getOperand(OpNo); |
1112 | 8 | assert(Op.isReg() && "Operand of movep is not a register!"); |
1113 | 8 | switch (Op.getReg()) { |
1114 | 8 | default: |
1115 | 0 | llvm_unreachable("Unknown register for movep!"); |
1116 | 8 | case Mips::ZERO: return 00 ; |
1117 | 8 | case Mips::S1: return 10 ; |
1118 | 8 | case Mips::V0: return 24 ; |
1119 | 8 | case Mips::V1: return 34 ; |
1120 | 8 | case Mips::S0: return 40 ; |
1121 | 8 | case Mips::S2: return 50 ; |
1122 | 8 | case Mips::S3: return 60 ; |
1123 | 8 | case Mips::S4: return 70 ; |
1124 | 8 | } |
1125 | 8 | } |
1126 | | |
1127 | | unsigned |
1128 | | MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, |
1129 | | SmallVectorImpl<MCFixup> &Fixups, |
1130 | 9 | const MCSubtargetInfo &STI) const { |
1131 | 9 | const MCOperand &MO = MI.getOperand(OpNo); |
1132 | 9 | assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); |
1133 | 9 | // The immediate is encoded as 'immediate >> 2'. |
1134 | 9 | unsigned Res = static_cast<unsigned>(MO.getImm()); |
1135 | 9 | assert((Res & 3) == 0); |
1136 | 9 | return Res >> 2; |
1137 | 9 | } |
1138 | | |
1139 | | #include "MipsGenMCCodeEmitter.inc" |