@@ -82,6 +82,10 @@ class MipsAsmParser : public MCTargetAsmParser {
82
82
MCSubtargetInfo &STI;
83
83
MCAsmParser &Parser;
84
84
MipsAssemblerOptions Options;
85
+ MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
86
+ // nullptr, which indicates that no function is currently
87
+ // selected. This usually happens after an '.end func'
88
+ // directive.
85
89
86
90
#define GET_ASSEMBLER_HEADER
87
91
#include " MipsGenAsmMatcher.inc"
@@ -285,6 +289,8 @@ class MipsAsmParser : public MCTargetAsmParser {
285
289
286
290
if (!isABI_O32 () && !useOddSPReg () != 0 )
287
291
report_fatal_error (" -mno-odd-spreg requires the O32 ABI" );
292
+
293
+ CurrentFn = nullptr ;
288
294
}
289
295
290
296
MCAsmParser &getParser () const { return Parser; }
@@ -3055,38 +3061,213 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3055
3061
parseDataDirective (8 , DirectiveID.getLoc ());
3056
3062
return false ;
3057
3063
}
3058
-
3059
3064
if (IDVal == " .ent" ) {
3060
- // Ignore this directive for now.
3061
- Parser.Lex ();
3065
+ StringRef SymbolName;
3066
+
3067
+ if (Parser.parseIdentifier (SymbolName)) {
3068
+ reportParseError (" expected identifier after .ent" );
3069
+ return false ;
3070
+ }
3071
+
3072
+ // There's an undocumented extension that allows an integer to
3073
+ // follow the name of the procedure which AFAICS is ignored by GAS.
3074
+ // Example: .ent foo,2
3075
+ if (getLexer ().isNot (AsmToken::EndOfStatement)) {
3076
+ if (getLexer ().isNot (AsmToken::Comma)) {
3077
+ // Even though we accept this undocumented extension for compatibility
3078
+ // reasons, the additional integer argument does not actually change
3079
+ // the behaviour of the '.ent' directive, so we would like to discourage
3080
+ // its use. We do this by not referring to the extended version in
3081
+ // error messages which are not directly related to its use.
3082
+ reportParseError (" unexpected token, expected end of statement" );
3083
+ return false ;
3084
+ }
3085
+ Parser.Lex (); // Eat the comma.
3086
+ const MCExpr *DummyNumber;
3087
+ int64_t DummyNumberVal;
3088
+ // If the user was explicitly trying to use the extended version,
3089
+ // we still give helpful extension-related error messages.
3090
+ if (Parser.parseExpression (DummyNumber)) {
3091
+ reportParseError (" expected number after comma" );
3092
+ return false ;
3093
+ }
3094
+ if (!DummyNumber->EvaluateAsAbsolute (DummyNumberVal)) {
3095
+ reportParseError (" expected an absolute expression after comma" );
3096
+ return false ;
3097
+ }
3098
+ }
3099
+
3100
+ // If this is not the end of the statement, report an error.
3101
+ if (getLexer ().isNot (AsmToken::EndOfStatement)) {
3102
+ reportParseError (" unexpected token, expected end of statement" );
3103
+ return false ;
3104
+ }
3105
+
3106
+ MCSymbol *Sym = getContext ().GetOrCreateSymbol (SymbolName);
3107
+
3108
+ getTargetStreamer ().emitDirectiveEnt (*Sym);
3109
+ CurrentFn = Sym;
3062
3110
return false ;
3063
3111
}
3064
3112
3065
3113
if (IDVal == " .end" ) {
3066
- // Ignore this directive for now.
3067
- Parser.Lex ();
3114
+ StringRef SymbolName;
3115
+
3116
+ if (Parser.parseIdentifier (SymbolName)) {
3117
+ reportParseError (" expected identifier after .end" );
3118
+ return false ;
3119
+ }
3120
+
3121
+ if (getLexer ().isNot (AsmToken::EndOfStatement)) {
3122
+ reportParseError (" unexpected token, expected end of statement" );
3123
+ return false ;
3124
+ }
3125
+
3126
+ if (CurrentFn == nullptr ) {
3127
+ reportParseError (" .end used without .ent" );
3128
+ return false ;
3129
+ }
3130
+
3131
+ if ((SymbolName != CurrentFn->getName ())) {
3132
+ reportParseError (" .end symbol does not match .ent symbol" );
3133
+ return false ;
3134
+ }
3135
+
3136
+ getTargetStreamer ().emitDirectiveEnd (SymbolName);
3137
+ CurrentFn = nullptr ;
3068
3138
return false ;
3069
3139
}
3070
3140
3071
3141
if (IDVal == " .frame" ) {
3072
- // Ignore this directive for now.
3073
- Parser.eatToEndOfStatement ();
3142
+ // .frame $stack_reg, frame_size_in_bytes, $return_reg
3143
+ SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1 > TmpReg;
3144
+ OperandMatchResultTy ResTy = ParseAnyRegister (TmpReg);
3145
+ if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3146
+ reportParseError (" expected stack register" );
3147
+ return false ;
3148
+ }
3149
+
3150
+ MipsOperand &StackRegOpnd = static_cast <MipsOperand &>(*TmpReg[0 ]);
3151
+ if (!StackRegOpnd.isGPRAsmReg ()) {
3152
+ reportParseError (StackRegOpnd.getStartLoc (),
3153
+ " expected general purpose register" );
3154
+ return false ;
3155
+ }
3156
+ unsigned StackReg = StackRegOpnd.getGPR32Reg ();
3157
+
3158
+ if (Parser.getTok ().is (AsmToken::Comma))
3159
+ Parser.Lex ();
3160
+ else {
3161
+ reportParseError (" unexpected token, expected comma" );
3162
+ return false ;
3163
+ }
3164
+
3165
+ // Parse the frame size.
3166
+ const MCExpr *FrameSize;
3167
+ int64_t FrameSizeVal;
3168
+
3169
+ if (Parser.parseExpression (FrameSize)) {
3170
+ reportParseError (" expected frame size value" );
3171
+ return false ;
3172
+ }
3173
+
3174
+ if (!FrameSize->EvaluateAsAbsolute (FrameSizeVal)) {
3175
+ reportParseError (" frame size not an absolute expression" );
3176
+ return false ;
3177
+ }
3178
+
3179
+ if (Parser.getTok ().is (AsmToken::Comma))
3180
+ Parser.Lex ();
3181
+ else {
3182
+ reportParseError (" unexpected token, expected comma" );
3183
+ return false ;
3184
+ }
3185
+
3186
+ // Parse the return register.
3187
+ TmpReg.clear ();
3188
+ ResTy = ParseAnyRegister (TmpReg);
3189
+ if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3190
+ reportParseError (" expected return register" );
3191
+ return false ;
3192
+ }
3193
+
3194
+ MipsOperand &ReturnRegOpnd = static_cast <MipsOperand &>(*TmpReg[0 ]);
3195
+ if (!ReturnRegOpnd.isGPRAsmReg ()) {
3196
+ reportParseError (ReturnRegOpnd.getStartLoc (),
3197
+ " expected general purpose register" );
3198
+ return false ;
3199
+ }
3200
+
3201
+ // If this is not the end of the statement, report an error.
3202
+ if (getLexer ().isNot (AsmToken::EndOfStatement)) {
3203
+ reportParseError (" unexpected token, expected end of statement" );
3204
+ return false ;
3205
+ }
3206
+
3207
+ getTargetStreamer ().emitFrame (StackReg, FrameSizeVal,
3208
+ ReturnRegOpnd.getGPR32Reg ());
3074
3209
return false ;
3075
3210
}
3076
3211
3077
3212
if (IDVal == " .set" ) {
3078
3213
return parseDirectiveSet ();
3079
3214
}
3080
3215
3081
- if (IDVal == " .fmask" ) {
3082
- // Ignore this directive for now.
3083
- Parser.eatToEndOfStatement ();
3084
- return false ;
3085
- }
3216
+ if (IDVal == " .mask" || IDVal == " .fmask" ) {
3217
+ // .mask bitmask, frame_offset
3218
+ // bitmask: One bit for each register used.
3219
+ // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
3220
+ // first register is expected to be saved.
3221
+ // Examples:
3222
+ // .mask 0x80000000, -4
3223
+ // .fmask 0x80000000, -4
3224
+ //
3086
3225
3087
- if (IDVal == " .mask" ) {
3088
- // Ignore this directive for now.
3089
- Parser.eatToEndOfStatement ();
3226
+ // Parse the bitmask
3227
+ const MCExpr *BitMask;
3228
+ int64_t BitMaskVal;
3229
+
3230
+ if (Parser.parseExpression (BitMask)) {
3231
+ reportParseError (" expected bitmask value" );
3232
+ return false ;
3233
+ }
3234
+
3235
+ if (!BitMask->EvaluateAsAbsolute (BitMaskVal)) {
3236
+ reportParseError (" bitmask not an absolute expression" );
3237
+ return false ;
3238
+ }
3239
+
3240
+ if (Parser.getTok ().is (AsmToken::Comma))
3241
+ Parser.Lex ();
3242
+ else {
3243
+ reportParseError (" unexpected token, expected comma" );
3244
+ return false ;
3245
+ }
3246
+
3247
+ // Parse the frame_offset
3248
+ const MCExpr *FrameOffset;
3249
+ int64_t FrameOffsetVal;
3250
+
3251
+ if (Parser.parseExpression (FrameOffset)) {
3252
+ reportParseError (" expected frame offset value" );
3253
+ return false ;
3254
+ }
3255
+
3256
+ if (!FrameOffset->EvaluateAsAbsolute (FrameOffsetVal)) {
3257
+ reportParseError (" frame offset not an absolute expression" );
3258
+ return false ;
3259
+ }
3260
+
3261
+ // If this is not the end of the statement, report an error.
3262
+ if (getLexer ().isNot (AsmToken::EndOfStatement)) {
3263
+ reportParseError (" unexpected token, expected end of statement" );
3264
+ return false ;
3265
+ }
3266
+
3267
+ if (IDVal == " .mask" )
3268
+ getTargetStreamer ().emitMask (BitMaskVal, FrameOffsetVal);
3269
+ else
3270
+ getTargetStreamer ().emitFMask (BitMaskVal, FrameOffsetVal);
3090
3271
return false ;
3091
3272
}
3092
3273
0 commit comments