From bd2926b0566908611787c688763cd36d8eb55a84 Mon Sep 17 00:00:00 2001 From: Zoran Jovanovic Date: Thu, 19 Dec 2013 16:25:00 +0000 Subject: [PATCH] Support for microMIPS control instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197696 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MicroMipsInstrFormats.td | 60 +++++++++++++++++++ lib/Target/Mips/MicroMipsInstrInfo.td | 10 ++++ lib/Target/Mips/MipsInstrFormats.td | 20 +++++-- lib/Target/Mips/MipsInstrInfo.td | 36 +++++------ test/MC/Mips/micromips-control-instructions.s | 57 ++++++++++++++++++ 5 files changed, 158 insertions(+), 25 deletions(-) create mode 100644 test/MC/Mips/micromips-control-instructions.s diff --git a/lib/Target/Mips/MicroMipsInstrFormats.td b/lib/Target/Mips/MicroMipsInstrFormats.td index b1c3fb808d3..acbfd4db15d 100644 --- a/lib/Target/Mips/MicroMipsInstrFormats.td +++ b/lib/Target/Mips/MicroMipsInstrFormats.td @@ -276,6 +276,66 @@ class BGEZAL_FM_MM 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 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 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 funct> : MMArch { bits<5> rs; bits<5> rt; diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 76463892fae..4f068dfe15c 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -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>; diff --git a/lib/Target/Mips/MipsInstrFormats.td b/lib/Target/Mips/MipsInstrFormats.td index 737a018c67a..21ee605ac02 100644 --- a/lib/Target/Mips/MipsInstrFormats.td +++ b/lib/Target/Mips/MipsInstrFormats.td @@ -401,7 +401,7 @@ class BGEZAL_FM 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 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 //===----------------------------------------------------------------------===// -class SYS_FM funct> +class SYS_FM funct> : StdArch { bits<20> code_; bits<32> Inst; @@ -496,7 +506,7 @@ class SYS_FM funct> // Break instruction format //===----------------------------------------------------------------------===// -class BRK_FM funct> +class BRK_FM funct> : StdArch { bits<10> code_1; bits<10> code_2; @@ -511,7 +521,7 @@ class BRK_FM funct> // Exception return format //===----------------------------------------------------------------------===// -class ER_FM funct> +class ER_FM funct> : StdArch { bits<32> Inst; let Inst{31-26} = 0x10; @@ -525,7 +535,7 @@ class ER_FM funct> // Enable/disable interrupt instruction format //===----------------------------------------------------------------------===// -class EI_FM sc> +class EI_FM sc> : StdArch { bits<32> Inst; bits<5> rt; diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 12bddf06993..641f37a6fa5 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -643,36 +643,32 @@ class BAL_BR_Pseudo : // Syscall class SYS_FT : InstSE<(outs), (ins uimm20:$code_), - !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI>; + !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI, opstr>; // Break class BRK_FT : 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 : InstSE<(outs), (ins), - opstr, [], NoItinerary, FrmOther>; + opstr, [], NoItinerary, FrmOther, opstr>; // Interrupts class DEI_FT : InstSE<(outs RO:$rt), (ins), - !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther>; + !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther, opstr>; // Wait class WAIT_FT : - 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 : InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)], - NoItinerary, FrmOther>; + NoItinerary, FrmOther, opstr>; let hasSideEffects = 1 in class TEQ_FT : @@ -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; -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 { diff --git a/test/MC/Mips/micromips-control-instructions.s b/test/MC/Mips/micromips-control-instructions.s new file mode 100644 index 00000000000..07fd777c9e8 --- /dev/null +++ b/test/MC/Mips/micromips-control-instructions.s @@ -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