@@ -116,6 +116,10 @@ void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const {
116116 Inst.getOperand (1 ).setReg (RegOp0);
117117}
118118
119+ bool MipsMCCodeEmitter::isMips16 (const MCSubtargetInfo &STI) const {
120+ return STI.hasFeature (Mips::FeatureMips16);
121+ }
122+
119123bool MipsMCCodeEmitter::isMicroMips (const MCSubtargetInfo &STI) const {
120124 return STI.hasFeature (Mips::FeatureMicroMips);
121125}
@@ -210,7 +214,7 @@ void MipsMCCodeEmitter::encodeInstruction(const MCInst &MI,
210214 IsLittleEndian ? llvm::endianness::little : llvm::endianness::big;
211215 if (Size == 2 ) {
212216 support::endian::write<uint16_t >(CB, Binary, Endian);
213- } else if (IsLittleEndian && isMicroMips (STI)) {
217+ } else if (IsLittleEndian && ( isMips16 (STI) || isMicroMips (STI) )) {
214218 support::endian::write<uint16_t >(CB, Binary >> 16 , Endian);
215219 support::endian::write<uint16_t >(CB, Binary & 0xffff , Endian);
216220 } else {
@@ -372,6 +376,42 @@ getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
372376 return 0 ;
373377}
374378
379+ // / getBranchTargetOpValueMips16 - Return binary encoding of the MIPS16
380+ // / branch target operand. This is for the 16-bit instructions, which
381+ // / do not support relocations.
382+ unsigned MipsMCCodeEmitter::getBranchTargetOpValueMips16 (
383+ const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
384+ const MCSubtargetInfo &STI) const {
385+ const MCOperand &MO = MI.getOperand (OpNo);
386+
387+ // If the destination is an immediate, divide by 2.
388+ if (MO.isImm ())
389+ return MO.getImm () >> 1 ;
390+
391+ assert (false &&
392+ " getBranchTargetOpValueMips16 expects only constant immediates" );
393+
394+ return 0 ;
395+ }
396+
397+ // / getBranchTarget16OpValueMips16 - Return binary encoding of the MIPS16
398+ // / branch target operand. If the machine operand requires relocation,
399+ // / record the relocation and return zero.
400+ unsigned MipsMCCodeEmitter::getBranchTarget16OpValueMips16 (
401+ const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
402+ const MCSubtargetInfo &STI) const {
403+ const MCOperand &MO = MI.getOperand (OpNo);
404+
405+ // If the destination is an immediate, divide by 2.
406+ if (MO.isImm ())
407+ return MO.getImm () >> 1 ;
408+ // FIXME: This should output a fixup, but MIPS16 fixups are not yet supported.
409+ assert (false &&
410+ " getBranchTarget16OpValueMips16 expects only constant immediates" );
411+
412+ return 0 ;
413+ }
414+
375415// / getBranchTarget21OpValue - Return binary encoding of the branch
376416// / target operand. If the machine operand requires relocation,
377417// / record the relocation and return zero.
@@ -518,6 +558,21 @@ getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
518558 return 0 ;
519559}
520560
561+ unsigned MipsMCCodeEmitter::getJumpTargetOpValueMips16 (
562+ const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
563+ const MCSubtargetInfo &STI) const {
564+ const MCOperand &MO = MI.getOperand (OpNo);
565+ // If the destination is an immediate, divide by 4.
566+ if (MO.isImm ())
567+ return MO.getImm () >> 2 ;
568+
569+ // FIXME: This should output a fixup, but MIPS16 fixups are not yet supported.
570+ assert (false &&
571+ " getJumpTargetOpValueMips16 expects only constant immediates" );
572+
573+ return 0 ;
574+ }
575+
521576unsigned MipsMCCodeEmitter::
522577getUImm5Lsl2Encoding (const MCInst &MI, unsigned OpNo,
523578 SmallVectorImpl<MCFixup> &Fixups,
@@ -562,6 +617,58 @@ getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo,
562617 return 0 ;
563618}
564619
620+ unsigned
621+ MipsMCCodeEmitter::getUImm8Lsl2Encoding (const MCInst &MI, unsigned OpNo,
622+ SmallVectorImpl<MCFixup> &Fixups,
623+ const MCSubtargetInfo &STI) const {
624+ const MCOperand &MO = MI.getOperand (OpNo);
625+ if (MO.isImm ()) {
626+ unsigned Value = MO.getImm ();
627+ return Value >> 2 ;
628+ }
629+
630+ return 0 ;
631+ }
632+
633+ unsigned
634+ MipsMCCodeEmitter::getSImm8Lsl3Encoding (const MCInst &MI, unsigned OpNo,
635+ SmallVectorImpl<MCFixup> &Fixups,
636+ const MCSubtargetInfo &STI) const {
637+ const MCOperand &MO = MI.getOperand (OpNo);
638+ if (MO.isImm ()) {
639+ unsigned Value = MO.getImm ();
640+ return Value >> 3 ;
641+ }
642+
643+ return 0 ;
644+ }
645+
646+ unsigned
647+ MipsMCCodeEmitter::getSImm11Lsl1Encoding (const MCInst &MI, unsigned OpNo,
648+ SmallVectorImpl<MCFixup> &Fixups,
649+ const MCSubtargetInfo &STI) const {
650+ const MCOperand &MO = MI.getOperand (OpNo);
651+ if (MO.isImm ()) {
652+ unsigned Value = MO.getImm ();
653+ return Value >> 1 ;
654+ }
655+
656+ return 0 ;
657+ }
658+
659+ unsigned
660+ MipsMCCodeEmitter::getSImm16Lsl1Encoding (const MCInst &MI, unsigned OpNo,
661+ SmallVectorImpl<MCFixup> &Fixups,
662+ const MCSubtargetInfo &STI) const {
663+ const MCOperand &MO = MI.getOperand (OpNo);
664+ if (MO.isImm ()) {
665+ unsigned Value = MO.getImm ();
666+ return Value >> 1 ;
667+ }
668+
669+ return 0 ;
670+ }
671+
565672unsigned MipsMCCodeEmitter::
566673getSImm9AddiuspValue (const MCInst &MI, unsigned OpNo,
567674 SmallVectorImpl<MCFixup> &Fixups,
@@ -598,6 +705,7 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
598705 if (Kind == MCExpr::Target) {
599706 const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
600707
708+ // FIXME: Need to add MIPS16 fixups to these cases once support is added.
601709 Mips::Fixups FixupKind = Mips::Fixups (0 );
602710 switch (MipsExpr->getKind ()) {
603711 case MipsMCExpr::MEK_None:
@@ -737,6 +845,114 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
737845 return getExprOpValue (MO.getExpr (),Fixups, STI);
738846}
739847
848+ // / Return binary encoding of MIPS16 save and restore operands.
849+ unsigned
850+ MipsMCCodeEmitter::getSaveRestoreEncoding (const MCInst &MI, unsigned OpNo,
851+ SmallVectorImpl<MCFixup> &Fixups,
852+ const MCSubtargetInfo &STI) const {
853+ union {
854+ struct {
855+ unsigned framesize : 8 ;
856+ unsigned s1 : 1 ;
857+ unsigned s0 : 1 ;
858+ unsigned ra : 1 ;
859+ unsigned aregs : 4 ;
860+ unsigned xsregs : 3 ;
861+ } bits;
862+ unsigned val;
863+ } Encoding;
864+
865+ Encoding.val = 0 ;
866+
867+ // The number of caller-saved regs for 'aregs' and saved 'xsregs' is
868+ // determined by the largest register number in the list. That is [$4-7] for
869+ // 'aregs' and [$18-23, $30] for 'xsregs'. All other regs below those are
870+ // implicitly handled. For example, reg $6 would also handle regs $4 and $5
871+ // even if they were not called out in the assembly code.
872+ // This is similar for the static registers in 'aregs', but the count is
873+ // determined by the smallest register number. For example, if only reg $4
874+ // were specified, then the other three argument regs would be handled.
875+ unsigned NumAregArgs = 0 ;
876+ unsigned NumAregStatics = 0 ;
877+ unsigned NumXsRegs = 0 ;
878+
879+ // Get saved "$s_" regs (xsregs) and caller-saved argument regs.
880+ while (OpNo < MI.getNumOperands () && MI.getOperand (OpNo).isReg ()) {
881+ switch (MI.getOperand (OpNo).getReg ()) {
882+ default : {
883+ unsigned RegIdx = getMachineOpValue (MI, MI.getOperand (OpNo), Fixups, STI);
884+ if (NumXsRegs < (RegIdx - 17 ))
885+ NumXsRegs = RegIdx - 17 ;
886+ break ;
887+ }
888+ case Mips::A0:
889+ case Mips::A0_64:
890+ if (NumAregArgs < 1 )
891+ NumAregArgs = 1 ;
892+ break ;
893+ case Mips::A1:
894+ case Mips::A1_64:
895+ if (NumAregArgs < 2 )
896+ NumAregArgs = 2 ;
897+ break ;
898+ case Mips::A2:
899+ case Mips::A2_64:
900+ if (NumAregArgs < 3 )
901+ NumAregArgs = 3 ;
902+ break ;
903+ case Mips::A3:
904+ case Mips::A3_64:
905+ NumAregArgs = 4 ;
906+ break ;
907+ case Mips::S0:
908+ case Mips::S0_64:
909+ Encoding.bits .s0 = 1 ;
910+ break ;
911+ case Mips::S1:
912+ case Mips::S1_64:
913+ Encoding.bits .s1 = 1 ;
914+ break ;
915+ case Mips::FP:
916+ case Mips::FP_64:
917+ NumXsRegs = 7 ;
918+ break ;
919+ case Mips::RA:
920+ case Mips::RA_64:
921+ Encoding.bits .ra = 1 ;
922+ break ;
923+ }
924+
925+ ++OpNo;
926+ }
927+
928+ // Instruction multiplies framesize value by 8.
929+ Encoding.bits .framesize = MI.getOperand (OpNo).getImm () >> 3 ;
930+ ++OpNo;
931+
932+ // Get static argument regs (ones saved at the end of the callee stack).
933+ while (OpNo < MI.getNumOperands () && MI.getOperand (OpNo).isReg ()) {
934+ unsigned RegIdx = getMachineOpValue (MI, MI.getOperand (OpNo), Fixups, STI);
935+ if (NumAregStatics < (8 - RegIdx))
936+ NumAregStatics = 8 - RegIdx;
937+
938+ ++OpNo;
939+ }
940+
941+ // Determine 'aregs' encoding. There are two special cases for when all
942+ // four argument regs are used.
943+ if (NumAregStatics == 4 ) {
944+ Encoding.bits .aregs = 0b1011 ;
945+ } else if (NumAregArgs == 4 ) {
946+ Encoding.bits .aregs = 0b1110 ;
947+ } else {
948+ Encoding.bits .aregs = (NumAregArgs << 2 ) | NumAregStatics;
949+ }
950+
951+ Encoding.bits .xsregs = NumXsRegs;
952+
953+ return Encoding.val ;
954+ }
955+
740956// / Return binary encoding of memory related operand.
741957// / If the offset operand requires relocation, record the relocation.
742958template <unsigned ShiftAmount>
0 commit comments