llvm.org GIT mirror llvm / fbdb8e1
[mips] Improve encapsulation of the .MIPS.abiflags implementation and limit scope of related enums Summary: Follow on to r212519 to improve the encapsulation and limit the scope of the enums. Also merged two very similar parser functions, fixed a bug where ASE's were not being reported, and marked CPR1's as being 128-bit when MSA is enabled. Differential Revision: http://reviews.llvm.org/D4384 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212522 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Sanders 5 years ago
8 changed file(s) with 396 addition(s) and 303 deletion(s). Raw diff Collapse all Expand all
3737 namespace {
3838 class MipsAssemblerOptions {
3939 public:
40 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true), fpAbiMode(0) {}
40 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
4141
4242 unsigned getATRegNum() { return aTReg; }
4343 bool setATReg(unsigned Reg);
4545 bool isReorder() { return reorder; }
4646 void setReorder() { reorder = true; }
4747 void setNoreorder() { reorder = false; }
48 void setFpAbiMode(int Mode) { fpAbiMode = Mode; }
4948
5049 bool isMacro() { return macro; }
5150 void setMacro() { macro = true; }
5251 void setNomacro() { macro = false; }
53 int getFpAbiMode() { return fpAbiMode; }
5452
5553 private:
5654 unsigned aTReg;
5755 bool reorder;
5856 bool macro;
59 int fpAbiMode;
6057 };
6158 }
6259
135132 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
136133 SmallVectorImpl &Instructions, bool isLoad,
137134 bool isImmOpnd);
138 bool reportParseError(StringRef ErrorMsg);
139 bool reportParseError(SMLoc Loc, StringRef ErrorMsg);
135 bool reportParseError(Twine ErrorMsg);
136 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
140137
141138 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
142139 bool parseRelocOperand(const MCExpr *&Res);
166163 bool parseDirectiveGpWord();
167164 bool parseDirectiveGpDWord();
168165 bool parseDirectiveModule();
166 bool parseDirectiveModuleFP();
167 bool parseFpABIValue(Val_GNU_MIPS_ABI &FpABI, StringRef Directive);
169168
170169 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
171170
23032302 return false;
23042303 }
23052304
2306 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
2305 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
23072306 SMLoc Loc = getLexer().getLoc();
23082307 Parser.eatToEndOfStatement();
23092308 return Error(Loc, ErrorMsg);
23102309 }
23112310
2312 bool MipsAsmParser::reportParseError(SMLoc Loc, StringRef ErrorMsg) {
2311 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
23132312 return Error(Loc, ErrorMsg);
23142313 }
23152314
24442443 }
24452444
24462445 bool MipsAsmParser::parseSetFpDirective() {
2447 int FpAbiMode;
2446 Val_GNU_MIPS_ABI FpAbiVal;
24482447 // Line can be: .set fp=32
24492448 // .set fp=xx
24502449 // .set fp=64
24562455 }
24572456 Parser.Lex(); // Eat '=' token.
24582457 Tok = Parser.getTok();
2459 if (Tok.is(AsmToken::Identifier)) {
2460 StringRef XX = Tok.getString();
2461 if (XX != "xx") {
2462 reportParseError("unsupported option");
2463 return false;
2464 }
2465 if (!isABI_O32()) {
2466 reportParseError("'set fp=xx'option requires O32 ABI");
2467 return false;
2468 }
2469 FpAbiMode = Val_GNU_MIPS_ABI_FP_XX;
2470 } else if (Tok.is(AsmToken::Integer)) {
2471 unsigned Value = Tok.getIntVal();
2472 if (Value != 32 && Value != 64) {
2473 reportParseError("unsupported option");
2474 return false;
2475 }
2476 if (Value == 32) {
2477 if (!isABI_O32()) {
2478 reportParseError("'set fp=32'option requires O32 ABI");
2479 return false;
2480 }
2481 FpAbiMode = Val_GNU_MIPS_ABI_FP_DOUBLE;
2482 } else {
2483 if (isABI_N32() || isABI_N64())
2484 FpAbiMode = Val_GNU_MIPS_ABI_FP_DOUBLE;
2485 else if (isABI_O32())
2486 FpAbiMode = Val_GNU_MIPS_ABI_FP_64;
2487 }
2488 }
2489 Parser.Lex(); // Eat option token.
2458
2459 if (!parseFpABIValue(FpAbiVal, ".set"))
2460 return false;
2461
24902462 if (getLexer().isNot(AsmToken::EndOfStatement)) {
24912463 reportParseError("unexpected token in statement");
24922464 return false;
24932465 }
2494 Options.setFpAbiMode(FpAbiMode);
2495 getTargetStreamer().emitDirectiveSetFp(FpAbiMode, isABI_O32());
2466 getTargetStreamer().emitDirectiveSetFp(FpAbiVal, isABI_O32());
24962467 Parser.Lex(); // Consume the EndOfStatement.
24972468 return false;
24982469 }
28162787 // Line can be: .module fp=32
28172788 // .module fp=xx
28182789 // .module fp=64
2819 unsigned FpAbiVal = 0;
28202790 if (!getTargetStreamer().getCanHaveModuleDir()) {
28212791 // TODO : get a better message.
28222792 reportParseError(".module directive must appear before any code");
28342804 return false;
28352805 }
28362806 Parser.Lex(); // Eat '=' token.
2837 Tok = Parser.getTok();
2838 if (Tok.is(AsmToken::Identifier)) {
2839 StringRef XX = Tok.getString();
2840 if (XX != "xx") {
2841 reportParseError("unsupported option");
2842 return false;
2843 }
2844 FpAbiVal = Val_GNU_MIPS_ABI_FP_XX;
2845 } else if (Tok.is(AsmToken::Integer)) {
2846 unsigned Value = Tok.getIntVal();
2847 if (Value != 32 && Value != 64) {
2848 reportParseError("unsupported value, expected 32 or 64");
2849 return false;
2850 }
2851 if (Value == 64) {
2852 if (isABI_N32() || isABI_N64())
2853 FpAbiVal = Val_GNU_MIPS_ABI_FP_DOUBLE;
2854 else if (isABI_O32())
2855 FpAbiVal = Val_GNU_MIPS_ABI_FP_64;
2856 } else if (isABI_O32())
2857 FpAbiVal = Val_GNU_MIPS_ABI_FP_DOUBLE;
2858 }
2859 Parser.Lex(); // Eat option token.
2807
2808 Val_GNU_MIPS_ABI FpABI;
2809 if (!parseFpABIValue(FpABI, ".module"))
2810 return false;
2811
28602812 if (getLexer().isNot(AsmToken::EndOfStatement)) {
28612813 reportParseError("unexpected token in statement");
28622814 return false;
28632815 }
2864 // Emit appropriate flags.
2865 getTargetStreamer().emitDirectiveModule(FpAbiVal, isABI_O32());
2866 getTargetStreamer().setFpABI(FpAbiVal);
2867 Parser.Lex(); // Consume the EndOfStatement.
2816
28682817 return false;
28692818 }
2819
2820 bool MipsAsmParser::parseFpABIValue(Val_GNU_MIPS_ABI &FpABI,
2821 StringRef Directive) {
2822 MCAsmLexer &Lexer = getLexer();
2823
2824 if (Lexer.is(AsmToken::Identifier)) {
2825 StringRef Value = Parser.getTok().getString();
2826 Parser.Lex();
2827
2828 if (Value != "xx") {
2829 reportParseError("unsupported value, expected 'xx', '32' or '64'");
2830 return false;
2831 }
2832
2833 if (!isABI_O32()) {
2834 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
2835 return false;
2836 }
2837
2838 FpABI = MipsABIFlagsSection::Val_GNU_MIPS_ABI_FP_XX;
2839 return true;
2840 }
2841
2842 if (Lexer.is(AsmToken::Integer)) {
2843 unsigned Value = Parser.getTok().getIntVal();
2844 Parser.Lex();
2845
2846 if (Value != 32 && Value != 64) {
2847 reportParseError("unsupported value, expected 'xx', '32' or '64'");
2848 return false;
2849 }
2850
2851 if (Value == 32) {
2852 if (!isABI_O32()) {
2853 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
2854 return false;
2855 }
2856
2857 FpABI = MipsABIFlagsSection::Val_GNU_MIPS_ABI_FP_DOUBLE;
2858 return true;
2859 } else {
2860 if (isABI_N32() || isABI_N64()) {
2861 FpABI = MipsABIFlagsSection::Val_GNU_MIPS_ABI_FP_DOUBLE;
2862 return true;
2863 }
2864
2865 if (isABI_O32()) {
2866 FpABI = MipsABIFlagsSection::Val_GNU_MIPS_ABI_FP_64;
2867 return true;
2868 }
2869
2870 llvm_unreachable("Unknown ABI");
2871 }
2872 }
2873
2874 return false;
2875 }
2876
28702877 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
28712878 StringRef IDVal = DirectiveID.getString();
28722879
0 add_llvm_library(LLVMMipsDesc
1 MipsABIFlagsSection.cpp
12 MipsAsmBackend.cpp
23 MipsELFObjectWriter.cpp
34 MipsELFStreamer.cpp
0 //===-- MipsABIFlagsSection.cpp - Mips ELF ABI Flags Section ---*- C++ -*--===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "MipsABIFlagsSection.h"
10
11 using namespace llvm;
12
13 StringRef MipsABIFlagsSection::getFpABIString(Val_GNU_MIPS_ABI Value,
14 bool Is32BitAbi) {
15 switch (Value) {
16 case MipsABIFlagsSection::Val_GNU_MIPS_ABI_FP_XX:
17 return "xx";
18 case MipsABIFlagsSection::Val_GNU_MIPS_ABI_FP_64:
19 return "64";
20 case MipsABIFlagsSection::Val_GNU_MIPS_ABI_FP_DOUBLE:
21 if (Is32BitAbi)
22 return "32";
23 return "64";
24 default:
25 llvm_unreachable("unsupported fp abi value");
26 }
27 }
28
29 namespace llvm {
30 MCStreamer &operator<<(MCStreamer &OS, MipsABIFlagsSection &ABIFlagsSection) {
31 // Write out a Elf_Internal_ABIFlags_v0 struct
32 OS.EmitIntValue(ABIFlagsSection.getVersion(), 2); // version
33 OS.EmitIntValue(ABIFlagsSection.getISALevel(), 1); // isa_level
34 OS.EmitIntValue(ABIFlagsSection.getISARevision(), 1); // isa_rev
35 OS.EmitIntValue(ABIFlagsSection.getGPRSize(), 1); // gpr_size
36 OS.EmitIntValue(ABIFlagsSection.getCPR1Size(), 1); // cpr1_size
37 OS.EmitIntValue(ABIFlagsSection.getCPR2Size(), 1); // cpr2_size
38 OS.EmitIntValue(ABIFlagsSection.getFpABI(), 1); // fp_abi
39 OS.EmitIntValue(ABIFlagsSection.getISAExtensionSet(), 4); // isa_ext
40 OS.EmitIntValue(ABIFlagsSection.getASESet(), 4); // ases
41 OS.EmitIntValue(ABIFlagsSection.getFlags1(), 4); // flags1
42 OS.EmitIntValue(ABIFlagsSection.getFlags2(), 4); // flags2
43 return OS;
44 }
45 }
0 //===-- MipsABIFlagsSection.h - Mips ELF ABI Flags Section -----*- C++ -*--===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef MIPSABIFLAGSSECTION_H
10 #define MIPSABIFLAGSSECTION_H
11
12 #include "llvm/MC/MCStreamer.h"
13
14 namespace llvm {
15
16 class MCStreamer;
17
18 struct MipsABIFlagsSection {
19 // Values for the xxx_size bytes of an ABI flags structure.
20 enum AFL_REG {
21 AFL_REG_NONE = 0x00, // No registers.
22 AFL_REG_32 = 0x01, // 32-bit registers.
23 AFL_REG_64 = 0x02, // 64-bit registers.
24 AFL_REG_128 = 0x03 // 128-bit registers.
25 };
26
27 // Masks for the ases word of an ABI flags structure.
28 enum AFL_ASE {
29 AFL_ASE_DSP = 0x00000001, // DSP ASE.
30 AFL_ASE_DSPR2 = 0x00000002, // DSP R2 ASE.
31 AFL_ASE_EVA = 0x00000004, // Enhanced VA Scheme.
32 AFL_ASE_MCU = 0x00000008, // MCU (MicroController) ASE.
33 AFL_ASE_MDMX = 0x00000010, // MDMX ASE.
34 AFL_ASE_MIPS3D = 0x00000020, // MIPS-3D ASE.
35 AFL_ASE_MT = 0x00000040, // MT ASE.
36 AFL_ASE_SMARTMIPS = 0x00000080, // SmartMIPS ASE.
37 AFL_ASE_VIRT = 0x00000100, // VZ ASE.
38 AFL_ASE_MSA = 0x00000200, // MSA ASE.
39 AFL_ASE_MIPS16 = 0x00000400, // MIPS16 ASE.
40 AFL_ASE_MICROMIPS = 0x00000800, // MICROMIPS ASE.
41 AFL_ASE_XPA = 0x00001000 // XPA ASE.
42 };
43
44 // Values for the isa_ext word of an ABI flags structure.
45 enum AFL_EXT {
46 AFL_EXT_XLR = 1, // RMI Xlr instruction.
47 AFL_EXT_OCTEON2 = 2, // Cavium Networks Octeon2.
48 AFL_EXT_OCTEONP = 3, // Cavium Networks OcteonP.
49 AFL_EXT_LOONGSON_3A = 4, // Loongson 3A.
50 AFL_EXT_OCTEON = 5, // Cavium Networks Octeon.
51 AFL_EXT_5900 = 6, // MIPS R5900 instruction.
52 AFL_EXT_4650 = 7, // MIPS R4650 instruction.
53 AFL_EXT_4010 = 8, // LSI R4010 instruction.
54 AFL_EXT_4100 = 9, // NEC VR4100 instruction.
55 AFL_EXT_3900 = 10, // Toshiba R3900 instruction.
56 AFL_EXT_10000 = 11, // MIPS R10000 instruction.
57 AFL_EXT_SB1 = 12, // Broadcom SB-1 instruction.
58 AFL_EXT_4111 = 13, // NEC VR4111/VR4181 instruction.
59 AFL_EXT_4120 = 14, // NEC VR4120 instruction.
60 AFL_EXT_5400 = 15, // NEC VR5400 instruction.
61 AFL_EXT_5500 = 16, // NEC VR5500 instruction.
62 AFL_EXT_LOONGSON_2E = 17, // ST Microelectronics Loongson 2E.
63 AFL_EXT_LOONGSON_2F = 18 // ST Microelectronics Loongson 2F.
64 };
65
66 // Values for the fp_abi word of an ABI flags structure.
67 enum Val_GNU_MIPS_ABI {
68 Val_GNU_MIPS_ABI_FP_ANY = 0,
69 Val_GNU_MIPS_ABI_FP_DOUBLE = 1,
70 Val_GNU_MIPS_ABI_FP_XX = 5,
71 Val_GNU_MIPS_ABI_FP_64 = 6
72 };
73
74 // Version of flags structure.
75 uint16_t Version;
76 // The level of the ISA: 1-5, 32, 64.
77 uint8_t ISALevel;
78 // The revision of ISA: 0 for MIPS V and below, 1-n otherwise.
79 uint8_t ISARevision;
80 // The size of general purpose registers.
81 AFL_REG GPRSize;
82 // The size of co-processor 1 registers.
83 AFL_REG CPR1Size;
84 // The size of co-processor 2 registers.
85 AFL_REG CPR2Size;
86 // The floating-point ABI.
87 Val_GNU_MIPS_ABI FpABI;
88 // Processor-specific extension.
89 uint32_t ISAExtensionSet;
90 // Mask of ASEs used.
91 uint32_t ASESet;
92
93 MipsABIFlagsSection()
94 : Version(0), ISALevel(0), ISARevision(0), GPRSize(AFL_REG_NONE),
95 CPR1Size(AFL_REG_NONE), CPR2Size(AFL_REG_NONE),
96 FpABI(Val_GNU_MIPS_ABI_FP_ANY), ISAExtensionSet(0), ASESet(0) {}
97
98 uint16_t getVersion() { return (uint16_t)Version; }
99 uint8_t getISALevel() { return (uint8_t)ISALevel; }
100 uint8_t getISARevision() { return (uint8_t)ISARevision; }
101 uint8_t getGPRSize() { return (uint8_t)GPRSize; }
102 uint8_t getCPR1Size() { return (uint8_t)CPR1Size; }
103 uint8_t getCPR2Size() { return (uint8_t)CPR2Size; }
104 uint8_t getFpABI() { return (uint8_t)FpABI; }
105 uint32_t getISAExtensionSet() { return (uint32_t)ISAExtensionSet; }
106 uint32_t getASESet() { return (uint32_t)ASESet; }
107 uint32_t getFlags1() { return 0; }
108 uint32_t getFlags2() { return 0; }
109
110 StringRef getFpABIString(Val_GNU_MIPS_ABI Value, bool Is32BitAbi);
111
112 template
113 void setISALevelAndRevisionFromPredicates(const PredicateLibrary &P) {
114 if (P.hasMips64()) {
115 ISALevel = 64;
116 if (P.hasMips64r6())
117 ISARevision = 6;
118 else if (P.hasMips64r2())
119 ISARevision = 2;
120 else
121 ISARevision = 1;
122 } else if (P.hasMips32()) {
123 ISALevel = 32;
124 if (P.hasMips32r6())
125 ISARevision = 6;
126 else if (P.hasMips32r2())
127 ISARevision = 2;
128 else
129 ISARevision = 1;
130 } else {
131 ISARevision = 0;
132 if (P.hasMips5())
133 ISALevel = 5;
134 else if (P.hasMips4())
135 ISALevel = 4;
136 else if (P.hasMips3())
137 ISALevel = 3;
138 else if (P.hasMips2())
139 ISALevel = 2;
140 else if (P.hasMips1())
141 ISALevel = 1;
142 else
143 llvm_unreachable("Unknown ISA level!");
144 }
145 }
146
147 template
148 void setGPRSizeFromPredicates(const PredicateLibrary &P) {
149 GPRSize = P.isGP64bit() ? AFL_REG_64 : AFL_REG_32;
150 }
151
152 template
153 void setCPR1SizeFromPredicates(const PredicateLibrary &P) {
154 if (P.mipsSEUsesSoftFloat())
155 CPR1Size = AFL_REG_NONE;
156 else if (P.hasMSA())
157 CPR1Size = AFL_REG_128;
158 else
159 CPR1Size = P.isFP64bit() ? AFL_REG_64 : AFL_REG_32;
160 }
161
162 template
163 void setASESetFromPredicates(const PredicateLibrary &P) {
164 ASESet = 0;
165 if (P.hasDSP())
166 ASESet |= AFL_ASE_DSP;
167 if (P.hasDSPR2())
168 ASESet |= AFL_ASE_DSPR2;
169 if (P.hasMSA())
170 ASESet |= AFL_ASE_MSA;
171 if (P.inMicroMipsMode())
172 ASESet |= AFL_ASE_MICROMIPS;
173 if (P.inMips16Mode())
174 ASESet |= AFL_ASE_MIPS16;
175 }
176
177 template
178 void setFpAbiFromPredicates(const PredicateLibrary &P) {
179 FpABI = Val_GNU_MIPS_ABI_FP_ANY;
180 if (P.isABI_N32() || P.isABI_N64())
181 FpABI = Val_GNU_MIPS_ABI_FP_DOUBLE;
182 else if (P.isABI_O32()) {
183 if (P.isFP64bit())
184 FpABI = Val_GNU_MIPS_ABI_FP_64;
185 else if (P.isABI_FPXX())
186 FpABI = Val_GNU_MIPS_ABI_FP_XX;
187 else
188 FpABI = Val_GNU_MIPS_ABI_FP_DOUBLE;
189 }
190 }
191
192 template
193 void setAllFromPredicates(const PredicateLibrary &P) {
194 setISALevelAndRevisionFromPredicates(P);
195 setGPRSizeFromPredicates(P);
196 setCPR1SizeFromPredicates(P);
197 setASESetFromPredicates(P);
198 setFpAbiFromPredicates(P);
199 }
200 };
201
202 MCStreamer &operator<<(MCStreamer &OS, MipsABIFlagsSection &ABIFlagsSection);
203 }
204
205 #endif
210210 setCanHaveModuleDir(false);
211211 }
212212
213 void MipsTargetAsmStreamer::emitDirectiveModule(unsigned Value,
214 bool is32BitAbi) {
213 void MipsTargetAsmStreamer::emitDirectiveModuleFP(Val_GNU_MIPS_ABI Value,
214 bool Is32BitAbi) {
215 MipsTargetStreamer::emitDirectiveModuleFP(Value, Is32BitAbi);
216
215217 StringRef ModuleValue;
216218 OS << "\t.module\tfp=";
217 switch (Value) {
218 case Val_GNU_MIPS_ABI_FP_XX:
219 ModuleValue = "xx";
220 break;
221 case Val_GNU_MIPS_ABI_FP_64:
222 ModuleValue = "64";
223 break;
224 case Val_GNU_MIPS_ABI_FP_DOUBLE:
225 if (is32BitAbi)
226 ModuleValue = "32";
227 else
228 ModuleValue = "64";
229 break;
230 default:
231 llvm_unreachable("unsupported .module value");
232 }
233 OS << ModuleValue << "\n";
234 }
235
236 void MipsTargetAsmStreamer::emitDirectiveSetFp(unsigned Value,
237 bool is32BitAbi) {
219 OS << ABIFlagsSection.getFpABIString(Value, Is32BitAbi) << "\n";
220 }
221
222 void MipsTargetAsmStreamer::emitDirectiveSetFp(Val_GNU_MIPS_ABI Value,
223 bool Is32BitAbi) {
238224 StringRef ModuleValue;
239225 OS << "\t.set\tfp=";
240 switch (Value) {
241 case Val_GNU_MIPS_ABI_FP_XX:
242 ModuleValue = "xx";
243 break;
244 case Val_GNU_MIPS_ABI_FP_64:
245 ModuleValue = "64";
246 break;
247 case Val_GNU_MIPS_ABI_FP_DOUBLE:
248 if (is32BitAbi)
249 ModuleValue = "32";
250 else
251 ModuleValue = "64";
252 break;
253 default:
254 llvm_unreachable("unsupported .set fp value");
255 }
256 OS << ModuleValue << "\n";
226 OS << ABIFlagsSection.getFpABIString(Value, Is32BitAbi) << "\n";
257227 }
258228
259229 void MipsTargetAsmStreamer::emitMipsAbiFlags() {
660630 ABIShndxSD.setAlignment(8);
661631 OS.SwitchSection(Sec);
662632
663 OS.EmitIntValue(MipsABIFlags.version, 2); // version
664 OS.EmitIntValue(MipsABIFlags.isa_level, 1); // isa_level
665 OS.EmitIntValue(MipsABIFlags.isa_rev, 1); // isa_rev
666 OS.EmitIntValue(MipsABIFlags.gpr_size, 1); // gpr_size
667 OS.EmitIntValue(MipsABIFlags.cpr1_size, 1); // cpr1_size
668 OS.EmitIntValue(MipsABIFlags.cpr2_size, 1); // cpr2_size
669 OS.EmitIntValue(MipsABIFlags.fp_abi, 1); // fp_abi
670 OS.EmitIntValue(MipsABIFlags.isa_ext, 4); // isa_ext
671 OS.EmitIntValue(MipsABIFlags.ases, 4); // ases
672 OS.EmitIntValue(MipsABIFlags.flags1, 4); // flags1
673 OS.EmitIntValue(MipsABIFlags.flags2, 4); // flags2
674 }
633 OS << ABIFlagsSection;
634 }
9393 void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
9494 MipsTargetStreamer &TS = getTargetStreamer();
9595 TS.setCanHaveModuleDir(false);
96
9697 if (MI->isDebugValue()) {
9798 SmallString<128> Str;
9899 raw_svector_ostream OS(Str);
659660 SectionKind::getDataRel()));
660661 }
661662 getTargetStreamer().updateABIInfo(*Subtarget);
662 unsigned FpAbiVal;
663 if (Subtarget->isABI_N32() || Subtarget->isABI_N64())
664 FpAbiVal = Val_GNU_MIPS_ABI_FP_DOUBLE;
665 else if(Subtarget->isABI_O32()) {
666 if (Subtarget->isFP64bit())
667 FpAbiVal = Val_GNU_MIPS_ABI_FP_64;
668 else if(Subtarget->isABI_FPXX())
669 FpAbiVal = Val_GNU_MIPS_ABI_FP_XX;
670 else
671 FpAbiVal = Val_GNU_MIPS_ABI_FP_DOUBLE;
672 }
673 getTargetStreamer().emitDirectiveModule(FpAbiVal, Subtarget->isABI_O32());
663 getTargetStreamer().emitDirectiveModuleFP(
664 getTargetStreamer().getABIFlagsSection().FpABI, Subtarget->isABI_O32());
674665 }
675666
676667 void MipsAsmPrinter::EmitJal(MCSymbol *Symbol) {
1111
1212 #include "llvm/MC/MCELFStreamer.h"
1313 #include "llvm/MC/MCStreamer.h"
14 #include "MCTargetDesc/MipsABIFlagsSection.h"
1415
1516 namespace llvm {
16 struct Elf_Internal_ABIFlags_v0 {
17 // Version of flags structure.
18 uint16_t version;
19 // The level of the ISA: 1-5, 32, 64.
20 uint8_t isa_level;
21 // The revision of ISA: 0 for MIPS V and below, 1-n otherwise.
22 uint8_t isa_rev;
23 // The size of general purpose registers.
24 uint8_t gpr_size;
25 // The size of co-processor 1 registers.
26 uint8_t cpr1_size;
27 // The size of co-processor 2 registers.
28 uint8_t cpr2_size;
29 // The floating-point ABI.
30 uint8_t fp_abi;
31 // Processor-specific extension.
32 uint32_t isa_ext;
33 // Mask of ASEs used.
34 uint32_t ases;
35 // Mask of general flags.
36 uint32_t flags1;
37 uint32_t flags2;
3817
39 Elf_Internal_ABIFlags_v0()
40 : version(0), isa_level(0), isa_rev(0), gpr_size(0), cpr1_size(0),
41 cpr2_size(0), fp_abi(0), isa_ext(0), ases(0), flags1(0), flags2(0) {}
42 };
18 class MipsABIFlagsSection;
4319
44 // Values for the xxx_size bytes of an ABI flags structure.
45 enum {
46 AFL_REG_NONE = 0x00, // No registers.
47 AFL_REG_32 = 0x01, // 32-bit registers.
48 AFL_REG_64 = 0x02, // 64-bit registers.
49 AFL_REG_128 = 0x03 // 128-bit registers.
50 };
51
52 // Masks for the ases word of an ABI flags structure.
53 enum {
54 AFL_ASE_DSP = 0x00000001, // DSP ASE.
55 AFL_ASE_DSPR2 = 0x00000002, // DSP R2 ASE.
56 AFL_ASE_EVA = 0x00000004, // Enhanced VA Scheme.
57 AFL_ASE_MCU = 0x00000008, // MCU (MicroController) ASE.
58 AFL_ASE_MDMX = 0x00000010, // MDMX ASE.
59 AFL_ASE_MIPS3D = 0x00000020, // MIPS-3D ASE.
60 AFL_ASE_MT = 0x00000040, // MT ASE.
61 AFL_ASE_SMARTMIPS = 0x00000080, // SmartMIPS ASE.
62 AFL_ASE_VIRT = 0x00000100, // VZ ASE.
63 AFL_ASE_MSA = 0x00000200, // MSA ASE.
64 AFL_ASE_MIPS16 = 0x00000400, // MIPS16 ASE.
65 AFL_ASE_MICROMIPS = 0x00000800, // MICROMIPS ASE.
66 AFL_ASE_XPA = 0x00001000 // XPA ASE.
67 };
68
69 // Values for the isa_ext word of an ABI flags structure.
70 enum {
71 AFL_EXT_XLR = 1, // RMI Xlr instruction.
72 AFL_EXT_OCTEON2 = 2, // Cavium Networks Octeon2.
73 AFL_EXT_OCTEONP = 3, // Cavium Networks OcteonP.
74 AFL_EXT_LOONGSON_3A = 4, // Loongson 3A.
75 AFL_EXT_OCTEON = 5, // Cavium Networks Octeon.
76 AFL_EXT_5900 = 6, // MIPS R5900 instruction.
77 AFL_EXT_4650 = 7, // MIPS R4650 instruction.
78 AFL_EXT_4010 = 8, // LSI R4010 instruction.
79 AFL_EXT_4100 = 9, // NEC VR4100 instruction.
80 AFL_EXT_3900 = 10, // Toshiba R3900 instruction.
81 AFL_EXT_10000 = 11, // MIPS R10000 instruction.
82 AFL_EXT_SB1 = 12, // Broadcom SB-1 instruction.
83 AFL_EXT_4111 = 13, // NEC VR4111/VR4181 instruction.
84 AFL_EXT_4120 = 14, // NEC VR4120 instruction.
85 AFL_EXT_5400 = 15, // NEC VR5400 instruction.
86 AFL_EXT_5500 = 16, // NEC VR5500 instruction.
87 AFL_EXT_LOONGSON_2E = 17, // ST Microelectronics Loongson 2E.
88 AFL_EXT_LOONGSON_2F = 18 // ST Microelectronics Loongson 2F.
89 };
90
91 // Values for the fp_abi word of an ABI flags structure.
92 enum {
93 Val_GNU_MIPS_ABI_FP_DOUBLE = 1,
94 Val_GNU_MIPS_ABI_FP_XX = 5,
95 Val_GNU_MIPS_ABI_FP_64 = 6
96 };
20 using Val_GNU_MIPS_ABI = MipsABIFlagsSection::Val_GNU_MIPS_ABI;
9721
9822 class MipsTargetStreamer : public MCTargetStreamer {
9923 public:
13256 virtual void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
13357 const MCSymbol &Sym, bool IsReg);
13458 // ABI Flags
135 virtual void emitDirectiveModule(unsigned Value, bool is32BitAbi){};
136 virtual void emitDirectiveSetFp(unsigned Value, bool is32BitAbi){};
59 virtual void emitDirectiveModuleFP(Val_GNU_MIPS_ABI Value, bool Is32BitAbi) {
60 ABIFlagsSection.FpABI = Value;
61 }
62 virtual void emitDirectiveSetFp(Val_GNU_MIPS_ABI Value, bool Is32BitAbi){};
13763 virtual void emitMipsAbiFlags(){};
13864 void setCanHaveModuleDir(bool Can) { canHaveModuleDirective = Can; }
13965 bool getCanHaveModuleDir() { return canHaveModuleDirective; }
14066
141 void setVersion(uint16_t Version) { MipsABIFlags.version = Version; }
142 void setISALevel(uint8_t Level) { MipsABIFlags.isa_level = Level; }
143 void setISARev(uint8_t Rev) { MipsABIFlags.isa_rev = Rev; }
144 void setGprSize(uint8_t Size) { MipsABIFlags.gpr_size = Size; }
145 void setCpr1Size(uint8_t Size) { MipsABIFlags.cpr1_size = Size; }
146 void setCpr2Size(uint8_t Size) { MipsABIFlags.cpr2_size = Size; }
147 void setFpABI(uint8_t Abi) { MipsABIFlags.fp_abi = Abi; }
148 void setIsaExt(uint32_t IsaExt) { MipsABIFlags.isa_ext = IsaExt; }
149 void setASEs(uint32_t Ases) { MipsABIFlags.ases = Ases; }
150 void setFlags1(uint32_t Flags) { MipsABIFlags.flags1 = Flags; }
151 void setFlags2(uint32_t Flags) { MipsABIFlags.flags2 = Flags; }
152
153 uint8_t getFPAbi() { return MipsABIFlags.fp_abi; }
15467 // This method enables template classes to set internal abi flags
15568 // structure values.
15669 template
15770 void updateABIInfo(const PredicateLibrary &P) {
158 setVersion(0); // Version, default value is 0.
159
160 if (P.hasMips64()) { // isa_level
161 setISALevel(64);
162 if (P.hasMips64r6())
163 setISARev(6);
164 else if (P.hasMips64r2())
165 setISARev(2);
166 else
167 setISARev(1);
168 } else if (P.hasMips32()) {
169 setISALevel(32);
170 if (P.hasMips32r6())
171 setISARev(6);
172 else if (P.hasMips32r2())
173 setISARev(2);
174 else
175 setISARev(1);
176 } else {
177 setISARev(0);
178 if (P.hasMips5())
179 setISALevel(5);
180 else if (P.hasMips4())
181 setISALevel(4);
182 else if (P.hasMips3())
183 setISALevel(3);
184 else if (P.hasMips2())
185 setISALevel(2);
186 else if (P.hasMips1())
187 setISALevel(1);
188 else
189 llvm_unreachable("Unknown ISA level!");
190 }
191
192 if (P.isGP64bit()) // GPR size.
193 setGprSize(AFL_REG_64);
194 else
195 setGprSize(AFL_REG_32);
196
197 // TODO: check for MSA128 value.
198 if (P.mipsSEUsesSoftFloat())
199 setCpr1Size(AFL_REG_NONE);
200 else if (P.isFP64bit())
201 setCpr1Size(AFL_REG_64);
202 else
203 setCpr1Size(AFL_REG_32);
204 setCpr2Size(AFL_REG_NONE); // Default value.
205
206 // Set ASE.
207 unsigned AseFlags = 0;
208 if (P.hasDSP())
209 AseFlags |= AFL_ASE_DSP;
210 if (P.hasDSPR2())
211 AseFlags |= AFL_ASE_DSPR2;
212 if (P.hasMSA())
213 AseFlags |= AFL_ASE_MSA;
214 if (P.inMicroMipsMode())
215 AseFlags |= AFL_ASE_MICROMIPS;
216 if (P.inMips16Mode())
217 AseFlags |= AFL_ASE_MIPS16;
218
219 if (P.isABI_N32() || P.isABI_N64())
220 setFpABI(Val_GNU_MIPS_ABI_FP_DOUBLE);
221 else if (P.isABI_O32()) {
222 if (P.isFP64bit())
223 setFpABI(Val_GNU_MIPS_ABI_FP_64);
224 else if (P.isABI_FPXX())
225 setFpABI(Val_GNU_MIPS_ABI_FP_XX);
226 else
227 setFpABI(Val_GNU_MIPS_ABI_FP_DOUBLE);
228 } else
229 setFpABI(0); // Default value.
71 ABIFlagsSection.setAllFromPredicates(P);
23072 }
23173
74 MipsABIFlagsSection &getABIFlagsSection() { return ABIFlagsSection; }
75
23276 protected:
233 Elf_Internal_ABIFlags_v0 MipsABIFlags;
77 MipsABIFlagsSection ABIFlagsSection;
23478
23579 private:
23680 bool canHaveModuleDirective;
277121 const MCSymbol &Sym, bool IsReg) override;
278122
279123 // ABI Flags
280 void emitDirectiveModule(unsigned Value, bool is32BitAbi) override;
281 void emitDirectiveSetFp(unsigned Value, bool is32BitAbi) override;
124 void emitDirectiveModuleFP(Val_GNU_MIPS_ABI Value, bool Is32BitAbi) override;
125 void emitDirectiveSetFp(Val_GNU_MIPS_ABI Value, bool Is32BitAbi) override;
282126 void emitMipsAbiFlags() override;
283127 };
284128
0 # RUN: llvm-mc %s -arch=mips -mcpu=mips32r2 -mattr=+msa | \
1 # RUN: FileCheck %s -check-prefix=CHECK-ASM
2 #
3 # RUN: llvm-mc %s -arch=mips -mcpu=mips32r2 -mattr=+msa -filetype=obj -o - | \
4 # RUN: llvm-readobj -sections -section-data -section-relocations - | \
5 # RUN: FileCheck %s -check-prefix=CHECK-OBJ
6
7 # CHECK-ASM: .module fp=32
8 # CHECK-ASM: .set fp=64
9
10 # Checking if the Mips.abiflags were correctly emitted.
11 # CHECK-OBJ: Section {
12 # CHECK-OBJ: Index: 5
13 # CHECK-OBJ: Name: .MIPS.abiflags (12)
14 # CHECK-OBJ: Type: (0x7000002A)
15 # CHECK-OBJ: Flags [ (0x2)
16 # CHECK-OBJ: SHF_ALLOC (0x2)
17 # CHECK-OBJ: ]
18 # CHECK-OBJ: Address: 0x0
19 # CHECK-OBJ: Offset: 0x50
20 # CHECK-OBJ: Size: 24
21 # CHECK-OBJ: Link: 0
22 # CHECK-OBJ: Info: 0
23 # CHECK-OBJ: AddressAlignment: 8
24 # CHECK-OBJ: EntrySize: 0
25 # CHECK-OBJ: Relocations [
26 # CHECK-OBJ: ]
27 # CHECK-OBJ: SectionData (
28 # CHECK-OBJ: 0000: 00002002 01030001 00000000 00000200 |.. .............|
29 # CHECK-OBJ: 0010: 00000000 00000000 |........|
30 # CHECK-OBJ: )
31 # CHECK-OBJ: }
32
33 .module fp=32
34 .set fp=64
35 # FIXME: Test should include gnu_attributes directive when implemented.
36 # An explicit .gnu_attribute must be checked against the effective
37 # command line options and any inconsistencies reported via a warning.