X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FAsmParser%2FMipsAsmParser.cpp;h=f36bd5fda61669af83f88c14751c3601948560ad;hb=10d5ff6b1dceec77c23cd200ef200e2e9dec4c85;hp=ff55905dfe73945d570f97d7d9b31336722fa26d;hpb=30116cd2e24a4a2b6c2771ef2665d655de93b984;p=oota-llvm.git diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index ff55905dfe7..f36bd5fda61 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -61,7 +61,7 @@ class MipsAsmParser : public MCTargetAsmParser { MCSubtargetInfo &STI; MCAsmParser &Parser; - MipsAssemblerOptions *Options; + MipsAssemblerOptions Options; #define GET_ASSEMBLER_HEADER @@ -92,6 +92,12 @@ class MipsAsmParser : public MCTargetAsmParser { bool tryParseRegisterOperand(SmallVectorImpl &Operands, StringRef Mnemonic); + bool needsExpansion(MCInst &Inst); + + void expandInstruction(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions); + void expandLoadImm(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions); bool reportParseError(StringRef ErrorMsg); bool parseMemOffset(const MCExpr *&Res); @@ -140,7 +146,6 @@ public: : MCTargetAsmParser(), STI(sti), Parser(parser) { // Initialize the set of available features. setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); - Options = new MipsAssemblerOptions(); } MCAsmParser &getParser() const { return Parser; } @@ -296,6 +301,68 @@ public: }; } +bool MipsAsmParser::needsExpansion(MCInst &Inst) { + + switch(Inst.getOpcode()) { + case Mips::LoadImm32Reg: + return true; + default: + return false; + } +} +void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions){ + switch(Inst.getOpcode()) { + case Mips::LoadImm32Reg: + return expandLoadImm(Inst, IDLoc, Instructions); + } + return; +} +void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions){ + MCInst *tmpInst = new MCInst(); + const MCOperand &ImmOp = Inst.getOperand(1); + assert(ImmOp.isImm() && "expected imediate operand kind"); + const MCOperand &RegOp = Inst.getOperand(0); + assert(RegOp.isReg() && "expected register operand kind"); + + int ImmValue = ImmOp.getImm(); + tmpInst->setLoc(IDLoc); + if ( 0 <= ImmValue && ImmValue <= 65535) { + // for 0 = j = 65535. + // li d,j => ori d,$zero,j + tmpInst->setOpcode(isMips64() ? Mips::ORi64 : Mips::ORi); + tmpInst->addOperand(MCOperand::CreateReg(RegOp.getReg())); + tmpInst->addOperand( + MCOperand::CreateReg(isMips64() ? Mips::ZERO_64 : Mips::ZERO)); + tmpInst->addOperand(MCOperand::CreateImm(ImmValue)); + Instructions.push_back(tmpInst); + } else if ( ImmValue < 0 && ImmValue >= -32768) { + // for -32768 = j < 0. + // li d,j => addiu d,$zero,j + tmpInst->setOpcode(Mips::ADDiu); //TODO:no ADDiu64 in td files? + tmpInst->addOperand(MCOperand::CreateReg(RegOp.getReg())); + tmpInst->addOperand( + MCOperand::CreateReg(isMips64() ? Mips::ZERO_64 : Mips::ZERO)); + tmpInst->addOperand(MCOperand::CreateImm(ImmValue)); + Instructions.push_back(tmpInst); + } else { + // for any other value of j that is representable as a 32-bit integer. + // li d,j => lui d,hi16(j) + // ori d,d,lo16(j) + tmpInst->setOpcode(isMips64() ? Mips::LUi64 : Mips::LUi); + tmpInst->addOperand(MCOperand::CreateReg(RegOp.getReg())); + tmpInst->addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); + Instructions.push_back(tmpInst); + tmpInst = new MCInst(); + tmpInst->setOpcode(isMips64() ? Mips::ORi64 : Mips::ORi); + tmpInst->addOperand(MCOperand::CreateReg(RegOp.getReg())); + tmpInst->addOperand(MCOperand::CreateReg(RegOp.getReg())); + tmpInst->addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); + tmpInst->setLoc(IDLoc); + Instructions.push_back(tmpInst); + } +} bool MipsAsmParser:: MatchAndEmitInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, @@ -303,7 +370,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, MCInst Inst; unsigned Kind; unsigned ErrorInfo; - SmallVector, 4> MapAndConstraints; + MatchInstMapAndConstraints MapAndConstraints; unsigned MatchResult = MatchInstructionImpl(Operands, Kind, Inst, MapAndConstraints, ErrorInfo, /*matchingInlineAsm*/ false); @@ -311,8 +378,17 @@ MatchAndEmitInstruction(SMLoc IDLoc, switch (MatchResult) { default: break; case Match_Success: { - Inst.setLoc(IDLoc); - Out.EmitInstruction(Inst); + if (needsExpansion(Inst)) { + SmallVector Instructions; + expandInstruction(Inst, IDLoc, Instructions); + for(unsigned i =0; i < Instructions.size(); i++){ + Inst = *(Instructions[i]); + Out.EmitInstruction(Inst); + } + } else { + Inst.setLoc(IDLoc); + Out.EmitInstruction(Inst); + } return false; } case Match_MissingFeature: @@ -375,7 +451,7 @@ int MipsAsmParser::matchRegisterName(StringRef Name) { .Default(-1); if (CC != -1) { - //64 bit register in Mips are following 32 bit definitions. + // 64 bit register in Mips are following 32 bit definitions. if (isMips64()) CC++; return CC; @@ -385,7 +461,7 @@ int MipsAsmParser::matchRegisterName(StringRef Name) { StringRef NumString = Name.substr(1); unsigned IntVal; if( NumString.getAsInteger(10, IntVal)) - return -1; //not integer + return -1; // not integer if (IntVal > 31) return -1; @@ -397,7 +473,7 @@ int MipsAsmParser::matchRegisterName(StringRef Name) { if(isFP64()) { return getReg(Mips::FGR64RegClassID, IntVal); } - //only even numbers available as register pairs + // only even numbers available as register pairs if (( IntVal > 31) || (IntVal%2 != 0)) return -1; return getReg(Mips::AFGR64RegClassID, IntVal/2); @@ -444,11 +520,11 @@ bool MipsAssemblerOptions::setATReg(unsigned Reg) { } unsigned MipsAsmParser::getATReg() { - unsigned Reg = Options->getATRegNum(); + unsigned Reg = Options.getATRegNum(); if (isMips64()) return getReg(Mips::CPU64RegsRegClassID,Reg); - else - return getReg(Mips::CPURegsRegClassID,Reg); + + return getReg(Mips::CPURegsRegClassID,Reg); } unsigned MipsAsmParser::getReg(int RC,int RegNo) { @@ -458,7 +534,7 @@ unsigned MipsAsmParser::getReg(int RC,int RegNo) { int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, StringRef Mnemonic) { if (Mnemonic.lower() == "rdhwr") { - //at the moment only hwreg29 is supported + // at the moment only hwreg29 is supported if (RegNum != 29) return -1; return Mips::HWR29; @@ -478,11 +554,11 @@ int MipsAsmParser::tryParseRegister(StringRef Mnemonic) { std::string lowerCase = Tok.getString().lower(); RegNum = matchRegisterName(lowerCase); } else if (Tok.is(AsmToken::Integer)) - RegNum = matchRegisterByNumber(static_cast (Tok.getIntVal()), + RegNum = matchRegisterByNumber(static_cast(Tok.getIntVal()), Mnemonic.lower()); else return RegNum; //error - //64 bit div operations require Mips::ZERO instead of MIPS::ZERO_64 + // 64 bit div operations require Mips::ZERO instead of MIPS::ZERO_64 if (isMips64() && RegNum == Mips::ZERO_64) { if (Mnemonic.find("ddiv") != StringRef::npos) RegNum = Mips::ZERO; @@ -497,11 +573,11 @@ bool MipsAsmParser:: SMLoc S = Parser.getTok().getLoc(); int RegNo = -1; - //FIXME: we should make a more generic method for CCR + // FIXME: we should make a more generic method for CCR if ((Mnemonic == "cfc1" || Mnemonic == "ctc1") && Operands.size() == 2 && Parser.getTok().is(AsmToken::Integer)){ - RegNo = Parser.getTok().getIntVal(); //get the int value - //at the moment only fcc0 is supported + RegNo = Parser.getTok().getIntVal(); // get the int value + // at the moment only fcc0 is supported if (RegNo == 0) RegNo = Mips::FCC0; } else @@ -517,8 +593,8 @@ bool MipsAsmParser:: bool MipsAsmParser::ParseOperand(SmallVectorImpl&Operands, StringRef Mnemonic) { - //Check if the current operand has a custom associated parser, if so, try to - //custom parse the operand, or fallback to the general approach. + // Check if the current operand has a custom associated parser, if so, try to + // custom parse the operand, or fallback to the general approach. OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); if (ResTy == MatchOperand_Success) return false; @@ -533,20 +609,20 @@ bool MipsAsmParser::ParseOperand(SmallVectorImpl&Operands, Error(Parser.getTok().getLoc(), "unexpected token in operand"); return true; case AsmToken::Dollar: { - //parse register + // parse register SMLoc S = Parser.getTok().getLoc(); Parser.Lex(); // Eat dollar token. - //parse register operand - if (!tryParseRegisterOperand(Operands,Mnemonic)) { + // parse register operand + if (!tryParseRegisterOperand(Operands, Mnemonic)) { if (getLexer().is(AsmToken::LParen)) { - //check if it is indexed addressing operand + // check if it is indexed addressing operand Operands.push_back(MipsOperand::CreateToken("(", S)); - Parser.Lex(); //eat parenthesis + Parser.Lex(); // eat parenthesis if (getLexer().isNot(AsmToken::Dollar)) return true; - Parser.Lex(); //eat dollar - if (tryParseRegisterOperand(Operands,Mnemonic)) + Parser.Lex(); // eat dollar + if (tryParseRegisterOperand(Operands, Mnemonic)) return true; if (!getLexer().is(AsmToken::RParen)) @@ -558,7 +634,7 @@ bool MipsAsmParser::ParseOperand(SmallVectorImpl&Operands, } return false; } - //maybe it is a symbol reference + // maybe it is a symbol reference StringRef Identifier; if (Parser.ParseIdentifier(Identifier)) return true; @@ -590,9 +666,9 @@ bool MipsAsmParser::ParseOperand(SmallVectorImpl&Operands, return false; } case AsmToken::Percent: { - //it is a symbol reference or constant expression + // it is a symbol reference or constant expression const MCExpr *IdVal; - SMLoc S = Parser.getTok().getLoc(); //start location of the operand + SMLoc S = Parser.getTok().getLoc(); // start location of the operand if (parseRelocOperand(IdVal)) return true; @@ -608,13 +684,13 @@ bool MipsAsmParser::ParseOperand(SmallVectorImpl&Operands, bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { Parser.Lex(); // eat % token - const AsmToken &Tok = Parser.getTok(); //get next token, operation + const AsmToken &Tok = Parser.getTok(); // get next token, operation if (Tok.isNot(AsmToken::Identifier)) return true; std::string Str = Tok.getIdentifier().str(); - Parser.Lex(); //eat identifier + Parser.Lex(); // eat identifier // now make expression from the rest of the operand const MCExpr *IdVal; SMLoc EndLoc; @@ -646,7 +722,7 @@ bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { // Check the type of the expression if (const MCConstantExpr *MCE = dyn_cast(IdVal)) { - //it's a constant, evaluate lo or hi value + // it's a constant, evaluate lo or hi value int Val = MCE->getValue(); if (Str == "lo") { Val = Val & 0xffff; @@ -943,7 +1019,7 @@ bool MipsAsmParser::parseSetNoAtDirective() { // line should look like: // .set noat // set at reg to 0 - Options->setATReg(0); + Options.setATReg(0); // eat noat Parser.Lex(); // if this is not the end of the statement, report error @@ -960,7 +1036,7 @@ bool MipsAsmParser::parseSetAtDirective() { // or .set at=$reg getParser().Lex(); if (getLexer().is(AsmToken::EndOfStatement)) { - Options->setATReg(1); + Options.setATReg(1); Parser.Lex(); // Consume the EndOfStatement return false; } else if (getLexer().is(AsmToken::Equal)) { @@ -975,7 +1051,7 @@ bool MipsAsmParser::parseSetAtDirective() { return false; } const AsmToken &Reg = Parser.getTok(); - if (!Options->setATReg(Reg.getIntVal())) { + if (!Options.setATReg(Reg.getIntVal())) { reportParseError("unexpected token in statement"); return false; } @@ -1000,7 +1076,7 @@ bool MipsAsmParser::parseSetReorderDirective() { reportParseError("unexpected token in statement"); return false; } - Options->setReorder(); + Options.setReorder(); Parser.Lex(); // Consume the EndOfStatement return false; } @@ -1012,7 +1088,7 @@ bool MipsAsmParser::parseSetNoReorderDirective() { reportParseError("unexpected token in statement"); return false; } - Options->setNoreorder(); + Options.setNoreorder(); Parser.Lex(); // Consume the EndOfStatement return false; } @@ -1024,7 +1100,7 @@ bool MipsAsmParser::parseSetMacroDirective() { reportParseError("unexpected token in statement"); return false; } - Options->setMacro(); + Options.setMacro(); Parser.Lex(); // Consume the EndOfStatement return false; } @@ -1036,11 +1112,11 @@ bool MipsAsmParser::parseSetNoMacroDirective() { reportParseError("`noreorder' must be set before `nomacro'"); return false; } - if (Options->isReorder()) { + if (Options.isReorder()) { reportParseError("`noreorder' must be set before `nomacro'"); return false; } - Options->setNomacro(); + Options.setNomacro(); Parser.Lex(); // Consume the EndOfStatement return false; } @@ -1094,8 +1170,6 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { } if (DirectiveID.getString() == ".set") { - // ignore this directive for now - //Parser.EatToEndOfStatement(); return parseDirectiveSet(); }