Support for microMIPS control instructions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197696 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Zoran Jovanovic 2013-12-19 16:25:00 +00:00
parent f779a6cacc
commit bd2926b056
5 changed files with 158 additions and 25 deletions

View File

@ -276,6 +276,66 @@ class BGEZAL_FM_MM<bits<5> funct> : MMArch {
let Inst{15-0} = offset;
}
class SYNC_FM_MM : MMArch {
bits<5> stype;
bits<32> Inst;
let Inst{31-26} = 0x00;
let Inst{25-21} = 0x0;
let Inst{20-16} = stype;
let Inst{15-6} = 0x1ad;
let Inst{5-0} = 0x3c;
}
class BRK_FM_MM : MMArch {
bits<10> code_1;
bits<10> code_2;
bits<32> Inst;
let Inst{31-26} = 0x0;
let Inst{25-16} = code_1;
let Inst{15-6} = code_2;
let Inst{5-0} = 0x07;
}
class SYS_FM_MM : MMArch {
bits<10> code_;
bits<32> Inst;
let Inst{31-26} = 0x0;
let Inst{25-16} = code_;
let Inst{15-6} = 0x22b;
let Inst{5-0} = 0x3c;
}
class WAIT_FM_MM : MMArch {
bits<32> Inst;
let Inst{31-26} = 0x00;
let Inst{25-16} = 0x00;
let Inst{15-6} = 0x24d;
let Inst{5-0} = 0x3c;
}
class ER_FM_MM<bits<10> funct> : MMArch {
bits<32> Inst;
let Inst{31-26} = 0x00;
let Inst{25-16} = 0x00;
let Inst{15-6} = funct;
let Inst{5-0} = 0x3c;
}
class EI_FM_MM<bits<10> funct> : MMArch {
bits<32> Inst;
bits<5> rt;
let Inst{31-26} = 0x00;
let Inst{25-21} = 0x00;
let Inst{20-16} = rt;
let Inst{15-6} = funct;
let Inst{5-0} = 0x3c;
}
class TEQ_FM_MM<bits<6> funct> : MMArch {
bits<5> rs;
bits<5> rt;

View File

@ -213,6 +213,16 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
def BLTZAL_MM : MMRel, BGEZAL_FT<"bltzal", brtarget_mm, GPR32Opnd>,
BGEZAL_FM_MM<0x01>;
/// Control Instructions
def SYNC_MM : MMRel, SYNC_FT<"sync">, SYNC_FM_MM;
def BREAK_MM : MMRel, BRK_FT<"break">, BRK_FM_MM;
def SYSCALL_MM : MMRel, SYS_FT<"syscall">, SYS_FM_MM;
def WAIT_MM : MMRel, WAIT_FT<"wait">, WAIT_FM_MM;
def ERET_MM : MMRel, ER_FT<"eret">, ER_FM_MM<0x3cd>;
def DERET_MM : MMRel, ER_FT<"deret">, ER_FM_MM<0x38d>;
def EI_MM : MMRel, DEI_FT<"ei", GPR32Opnd>, EI_FM_MM<0x15d>;
def DI_MM : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM_MM<0x11d>;
/// Trap Instructions
def TEQ_MM : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM_MM<0x0>;
def TGE_MM : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM_MM<0x08>;

View File

@ -401,7 +401,7 @@ class BGEZAL_FM<bits<5> funct> : StdArch {
let Inst{15-0} = offset;
}
class SYNC_FM {
class SYNC_FM : StdArch {
bits<5> stype;
bits<32> Inst;
@ -479,11 +479,21 @@ class TEQI_FM<bits<5> funct> : StdArch {
let Inst{20-16} = funct;
let Inst{15-0} = imm16;
}
class WAIT_FM : StdArch {
bits<32> Inst;
let Inst{31-26} = 0x10;
let Inst{25} = 1;
let Inst{24-6} = 0;
let Inst{5-0} = 0x20;
}
//===----------------------------------------------------------------------===//
// System calls format <op|code_|funct>
//===----------------------------------------------------------------------===//
class SYS_FM<bits<6> funct>
class SYS_FM<bits<6> funct> : StdArch
{
bits<20> code_;
bits<32> Inst;
@ -496,7 +506,7 @@ class SYS_FM<bits<6> funct>
// Break instruction format <op|code_1|funct>
//===----------------------------------------------------------------------===//
class BRK_FM<bits<6> funct>
class BRK_FM<bits<6> funct> : StdArch
{
bits<10> code_1;
bits<10> code_2;
@ -511,7 +521,7 @@ class BRK_FM<bits<6> funct>
// Exception return format <Cop0|1|0|funct>
//===----------------------------------------------------------------------===//
class ER_FM<bits<6> funct>
class ER_FM<bits<6> funct> : StdArch
{
bits<32> Inst;
let Inst{31-26} = 0x10;
@ -525,7 +535,7 @@ class ER_FM<bits<6> funct>
// Enable/disable interrupt instruction format <Cop0|MFMC0|rt|12|0|sc|0|0>
//===----------------------------------------------------------------------===//
class EI_FM<bits<1> sc>
class EI_FM<bits<1> sc> : StdArch
{
bits<32> Inst;
bits<5> rt;

View File

@ -643,36 +643,32 @@ class BAL_BR_Pseudo<Instruction RealInst> :
// Syscall
class SYS_FT<string opstr> :
InstSE<(outs), (ins uimm20:$code_),
!strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI>;
!strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI, opstr>;
// Break
class BRK_FT<string opstr> :
InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
!strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary, FrmOther>;
!strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary,
FrmOther, opstr>;
// (D)Eret
class ER_FT<string opstr> :
InstSE<(outs), (ins),
opstr, [], NoItinerary, FrmOther>;
opstr, [], NoItinerary, FrmOther, opstr>;
// Interrupts
class DEI_FT<string opstr, RegisterOperand RO> :
InstSE<(outs RO:$rt), (ins),
!strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther>;
!strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther, opstr>;
// Wait
class WAIT_FT<string opstr> :
InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther> {
let Inst{31-26} = 0x10;
let Inst{25} = 1;
let Inst{24-6} = 0;
let Inst{5-0} = 0x20;
}
InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther, opstr>;
// Sync
let hasSideEffects = 1 in
class SYNC_FT :
class SYNC_FT<string opstr> :
InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)],
NoItinerary, FrmOther>;
NoItinerary, FrmOther, opstr>;
let hasSideEffects = 1 in
class TEQ_FT<string opstr, RegisterOperand RO> :
@ -984,7 +980,7 @@ def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, IIStore>, LW_FM<0x2a>;
def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, IIStore>, LW_FM<0x2e>;
}
def SYNC : SYNC_FT, SYNC_FM;
def SYNC : MMRel, SYNC_FT<"sync">, SYNC_FM;
def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>;
def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>;
def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>;
@ -999,17 +995,17 @@ def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>;
def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>;
def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>;
def BREAK : BRK_FT<"break">, BRK_FM<0xd>;
def SYSCALL : SYS_FT<"syscall">, SYS_FM<0xc>;
def BREAK : MMRel, BRK_FT<"break">, BRK_FM<0xd>;
def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>;
def TRAP : TrapBase<BREAK>;
def ERET : ER_FT<"eret">, ER_FM<0x18>;
def DERET : ER_FT<"deret">, ER_FM<0x1f>;
def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18>;
def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f>;
def EI : DEI_FT<"ei", GPR32Opnd>, EI_FM<1>;
def DI : DEI_FT<"di", GPR32Opnd>, EI_FM<0>;
def EI : MMRel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>;
def DI : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>;
def WAIT : WAIT_FT<"wait">;
def WAIT : MMRel, WAIT_FT<"wait">, WAIT_FM;
/// Load-linked, Store-conditional
let Predicates = [NotInMicroMips] in {

View File

@ -0,0 +1,57 @@
# RUN: llvm-mc %s -triple=mipsel -show-encoding -mattr=micromips \
# RUN: | FileCheck -check-prefix=CHECK-EL %s
# RUN: llvm-mc %s -triple=mips -show-encoding -mattr=micromips \
# RUN: | FileCheck -check-prefix=CHECK-EB %s
# Check that the assembler can handle the documented syntax
# for control instructions.
#------------------------------------------------------------------------------
# microMIPS Control Instructions
#------------------------------------------------------------------------------
# Little endian
#------------------------------------------------------------------------------
# CHECK-EL: break # encoding: [0x00,0x00,0x07,0x00]
# CHECK-EL: break 7, 0 # encoding: [0x07,0x00,0x07,0x00]
# CHECK-EL: break 7, 5 # encoding: [0x07,0x00,0x47,0x01]
# CHECK-EL: syscall # encoding: [0x00,0x00,0xfc,0x8a]
# CHECK-EL: syscall 13396 # encoding: [0x54,0x00,0xfc,0x8a]
# CHECK-EL: eret # encoding: [0x00,0x00,0x7c,0xf3]
# CHECK-EL: deret # encoding: [0x00,0x00,0x7c,0xe3]
# CHECK-EL: di # encoding: [0x00,0x00,0x7c,0x47]
# CHECK-EL: di # encoding: [0x00,0x00,0x7c,0x47]
# CHECK-EL: di $10 # encoding: [0x0a,0x00,0x7c,0x47]
# CHECK-EL: ei # encoding: [0x00,0x00,0x7c,0x57]
# CHECK-EL: ei # encoding: [0x00,0x00,0x7c,0x57]
# CHECK-EL: ei $10 # encoding: [0x0a,0x00,0x7c,0x57]
# CHECK-EL: wait # encoding: [0x00,0x00,0x7c,0x93]
#------------------------------------------------------------------------------
# Big endian
#------------------------------------------------------------------------------
# CHECK-EB: break # encoding: [0x00,0x00,0x00,0x07]
# CHECK-EB: break 7, 0 # encoding: [0x00,0x07,0x00,0x07]
# CHECK-EB: break 7, 5 # encoding: [0x00,0x07,0x01,0x47]
# CHECK-EB: syscall # encoding: [0x00,0x00,0x8a,0xfc]
# CHECK-EB: syscall 13396 # encoding: [0x00,0x54,0x8a,0xfc]
# CHECK-EB: eret # encoding: [0x00,0x00,0xf3,0x7c]
# CHECK-EB: deret # encoding: [0x00,0x00,0xe3,0x7c]
# CHECK-EB: di # encoding: [0x00,0x00,0x47,0x7c]
# CHECK-EB: di # encoding: [0x00,0x00,0x47,0x7c]
# CHECK-EB: di $10 # encoding: [0x00,0x0a,0x47,0x7c]
# CHECK-EB: ei # encoding: [0x00,0x00,0x57,0x7c]
# CHECK-EB: ei # encoding: [0x00,0x00,0x57,0x7c]
# CHECK-EB: ei $10 # encoding: [0x00,0x0a,0x57,0x7c]
# CHECK-EB: wait # encoding: [0x00,0x00,0x93,0x7c]
break
break 7
break 7,5
syscall
syscall 0x3454
eret
deret
di
di $0
di $10
ei
ei $0
ei $10
wait