summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2008-12-23 19:10:25 +0000
committerNick Clifton <nickc@redhat.com>2008-12-23 19:10:25 +0000
commit76f667654ece0d5a90ac68816204263e0b31ad90 (patch)
tree01d37a8b544ed39ad705010f52e06667b121a3d5 /cpu
parentc5615800f5c110dbaaeb38e72d94f67f96bda6d2 (diff)
downloadbinutils-redhat-76f667654ece0d5a90ac68816204263e0b31ad90.tar.gz
Diffstat (limited to 'cpu')
-rw-r--r--cpu/ChangeLog5
-rw-r--r--cpu/lm32.cpu932
-rw-r--r--cpu/lm32.opc235
3 files changed, 1172 insertions, 0 deletions
diff --git a/cpu/ChangeLog b/cpu/ChangeLog
index 707c585560..671bc11a9d 100644
--- a/cpu/ChangeLog
+++ b/cpu/ChangeLog
@@ -1,3 +1,8 @@
+2008-12-23 Jon Beniston <jon@beniston.com>
+
+ * lm32.cpu: New file.
+ * lm32.opc: New file.
+
2008-01-29 Alan Modra <amodra@bigpond.net.au>
* mt.opc (parse_imm16): Apply 2007-09-26 opcodes/mt-asm.c change
diff --git a/cpu/lm32.cpu b/cpu/lm32.cpu
new file mode 100644
index 0000000000..cf8261563e
--- /dev/null
+++ b/cpu/lm32.cpu
@@ -0,0 +1,932 @@
+; Lattice Mico32 CPU description. -*- Scheme -*-
+; Copyright 2008 Free Software Foundation, Inc.
+; Contributed by Jon Beniston <jon@beniston.com>
+;
+; This file is part of the GNU Binutils.
+;
+; This program is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program; if not, write to the Free Software
+; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+; MA 02110-1301, USA.
+
+(include "simplify.inc")
+
+(define-arch
+ (name lm32) ; name of cpu family
+ (comment "Lattice Mico32")
+ (default-alignment aligned)
+ (insn-lsb0? #t)
+ (machs lm32)
+ (isas lm32)
+)
+
+
+; Instruction sets.
+
+(define-isa
+ (name lm32)
+ (comment "Lattice Mico32 ISA")
+ (default-insn-word-bitsize 32)
+ (default-insn-bitsize 32)
+ (base-insn-bitsize 32)
+ (decode-assist (31 30 29 28 27 26))
+)
+
+
+; Cpu family definitions.
+
+(define-cpu
+ ; cpu names must be distinct from the architecture name and machine name
+ (name lm32bf)
+ (comment "Lattice Mico32 CPU")
+ (endian big)
+ (word-bitsize 32)
+)
+
+(define-mach
+ (name lm32)
+ (comment "Lattice Mico32 MACH")
+ (cpu lm32bf)
+)
+
+(define-model
+ (name lm32)
+ (comment "Lattice Mico32 reference implementation")
+ (mach lm32)
+ (unit u-exec "Execution unit" ()
+ 1 1 () () () ())
+)
+
+
+; Hardware elements.
+
+(dnh h-pc "Program counter" (PC) (pc) () () ())
+
+(dnh h-gr "General purpose registers"
+ ()
+ (register SI (32))
+ (keyword "" (
+ (gp 26) (fp 27) (sp 28) (ra 29) (ea 30) (ba 31)
+ (r0 0) (r1 1) (r2 2) (r3 3)
+ (r4 4) (r5 5) (r6 6) (r7 7)
+ (r8 8) (r9 9) (r10 10) (r11 11)
+ (r12 12) (r13 13) (r14 14) (r15 15)
+ (r16 16) (r17 17) (r18 18) (r19 19)
+ (r20 20) (r21 21) (r22 22) (r23 23)
+ (r24 24) (r25 25) (r26 26) (r27 27)
+ (r28 28) (r29 29) (r30 30) (r31 31)
+ )
+ )
+ () ()
+)
+
+(dnh h-csr "Control and status registers"
+ ()
+ (register SI (32))
+ (keyword "" (
+ (IE 0) (IM 1) (IP 2)
+ (ICC 3) (DCC 4)
+ (CC 5)
+ (CFG 6)
+ (EBA 7)
+ (DC 8)
+ (DEBA 9)
+ (JTX 14) (JRX 15)
+ (BP0 16) (BP1 17) (BP2 18) (BP3 19)
+ (WP0 24) (WP1 25) (WP2 26) (WP3 27)
+ )
+ )
+ () ()
+)
+
+
+; Instruction fields.
+
+(dnf f-opcode "opcode field" () 31 6)
+(dnf f-r0 "register index 0 field" () 25 5)
+(dnf f-r1 "register index 1 field" () 20 5)
+(dnf f-r2 "register index 2 field" () 15 5)
+(dnf f-resv0 "reserved" (RESERVED) 10 11)
+(dnf f-shift "shift amount field" () 4 5)
+(df f-imm "signed immediate field" () 15 16 INT #f #f)
+(dnf f-uimm "unsigned immediate field" () 15 16)
+(dnf f-csr "csr field" () 25 5)
+(dnf f-user "user defined field" () 10 11)
+(dnf f-exception "exception field" () 25 26)
+
+(df f-branch "branch offset field" (PCREL-ADDR) 15 16 INT
+ ((value pc) (sra SI (sub SI value pc) 2))
+ ((value pc) (add SI pc (sra SI (sll SI value 16) 14)))
+)
+(df f-call "call offset field" (PCREL-ADDR) 25 26 INT
+ ((value pc) (sra SI (sub SI value pc) 2))
+ ((value pc) (add SI pc (sra SI (sll SI value 6) 4)))
+)
+
+
+; Operands.
+
+(dnop r0 "register 0" () h-gr f-r0)
+(dnop r1 "register 1" () h-gr f-r1)
+(dnop r2 "register 2" () h-gr f-r2)
+(dnop shift "shift amout" () h-uint f-shift)
+(dnop imm "signed immediate" () h-sint f-imm)
+(dnop uimm "unsigned immediate" () h-uint f-uimm)
+(dnop branch "branch offset" () h-iaddr f-branch)
+(dnop call "call offset" () h-iaddr f-call)
+(dnop csr "csr" () h-csr f-csr)
+(dnop user "user" () h-uint f-user)
+(dnop exception "exception" () h-uint f-exception)
+
+(define-operand
+ (name hi16)
+ (comment "high 16-bit immediate")
+ (attrs)
+ (type h-uint)
+ (index f-uimm)
+ (handlers (parse "hi16"))
+)
+
+(define-operand
+ (name lo16)
+ (comment "low 16-bit immediate")
+ (attrs)
+ (type h-uint)
+ (index f-uimm)
+ (handlers (parse "lo16"))
+)
+
+(define-operand
+ (name gp16)
+ (comment "gp relative 16-bit immediate")
+ (attrs)
+ (type h-sint)
+ (index f-imm)
+ (handlers (parse "gp16"))
+)
+
+(define-operand
+ (name got16)
+ (comment "got 16-bit immediate")
+ (attrs)
+ (type h-sint)
+ (index f-imm)
+ (handlers (parse "got16"))
+)
+
+(define-operand
+ (name gotoffhi16)
+ (comment "got offset high 16-bit immediate")
+ (attrs)
+ (type h-sint)
+ (index f-imm)
+ (handlers (parse "gotoff_hi16"))
+)
+
+(define-operand
+ (name gotofflo16)
+ (comment "got offset low 16-bit immediate")
+ (attrs)
+ (type h-sint)
+ (index f-imm)
+ (handlers (parse "gotoff_lo16"))
+)
+
+
+; Enumerations.
+
+(define-normal-insn-enum
+ opcodes "opcodes" () OP_ f-opcode
+ (("ADD" 45)
+ ("ADDI" 13)
+ ("AND" 40)
+ ("ANDI" 8)
+ ("ANDHI" 24)
+ ("B" 48)
+ ("BI" 56)
+ ("BE" 17)
+ ("BG" 18)
+ ("BGE" 19)
+ ("BGEU" 20)
+ ("BGU" 21)
+ ("BNE" 23)
+ ("CALL" 54)
+ ("CALLI" 62)
+ ("CMPE" 57)
+ ("CMPEI" 25)
+ ("CMPG" 58)
+ ("CMPGI" 26)
+ ("CMPGE" 59)
+ ("CMPGEI" 27)
+ ("CMPGEU" 60)
+ ("CMPGEUI" 28)
+ ("CMPGU" 61)
+ ("CMPGUI" 29)
+ ("CMPNE" 63)
+ ("CMPNEI" 31)
+ ("DIVU" 35)
+ ("LB" 4)
+ ("LBU" 16)
+ ("LH" 7)
+ ("LHU" 11)
+ ("LW" 10)
+ ("MODU" 49)
+ ("MUL" 34)
+ ("MULI" 2)
+ ("NOR" 33)
+ ("NORI" 1)
+ ("OR" 46)
+ ("ORI" 14)
+ ("ORHI" 30)
+ ("RAISE" 43)
+ ("RCSR" 36)
+ ("SB" 12)
+ ("SEXTB" 44)
+ ("SEXTH" 55)
+ ("SH" 3)
+ ("SL" 47)
+ ("SLI" 15)
+ ("SR" 37)
+ ("SRI" 5)
+ ("SRU" 32)
+ ("SRUI" 0)
+ ("SUB" 50)
+ ("SW" 22)
+ ("USER" 51)
+ ("WCSR" 52)
+ ("XNOR" 41)
+ ("XNORI" 9)
+ ("XOR" 38)
+ ("XORI" 6)
+ )
+)
+
+
+; Instructions. Note: Reg-reg must come before reg-imm.
+
+(dni add "add" ()
+ "add $r2,$r0,$r1"
+ (+ OP_ADD r0 r1 r2 (f-resv0 0))
+ (set r2 (add r0 r1))
+ ()
+)
+
+(dni addi "add immediate" ()
+ "addi $r1,$r0,$imm"
+ (+ OP_ADDI r0 r1 imm)
+ (set r1 (add r0 (ext SI (trunc HI imm))))
+ ()
+)
+
+(dni and "and" ()
+ "and $r2,$r0,$r1"
+ (+ OP_AND r0 r1 r2 (f-resv0 0))
+ (set r2 (and r0 r1))
+ ()
+)
+
+(dni andi "and immediate" ()
+ "andi $r1,$r0,$uimm"
+ (+ OP_ANDI r0 r1 uimm)
+ (set r1 (and r0 (zext SI uimm)))
+ ()
+)
+
+(dni andhii "and high immediate" ()
+ "andhi $r1,$r0,$hi16"
+ (+ OP_ANDHI r0 r1 hi16)
+ (set r1 (and r0 (sll SI hi16 16)))
+ ()
+)
+
+(dni b "branch" ()
+ "b $r0"
+ (+ OP_B r0 (f-r1 0) (f-r2 0) (f-resv0 0))
+ (set pc (c-call USI "@cpu@_b_insn" r0 f-r0))
+ ()
+)
+
+(dni bi "branch immediate" ()
+ "bi $call"
+ (+ OP_BI call)
+ (set pc (ext SI call))
+ ()
+)
+
+(dni be "branch equal" ()
+ "be $r0,$r1,$branch"
+ (+ OP_BE r0 r1 branch)
+ (if (eq r0 r1)
+ (set pc branch)
+ )
+ ()
+)
+
+(dni bg "branch greater" ()
+ "bg $r0,$r1,$branch"
+ (+ OP_BG r0 r1 branch)
+ (if (gt r0 r1)
+ (set pc branch)
+ )
+ ()
+)
+
+(dni bge "branch greater or equal" ()
+ "bge $r0,$r1,$branch"
+ (+ OP_BGE r0 r1 branch)
+ (if (ge r0 r1)
+ (set pc branch)
+ )
+ ()
+)
+
+(dni bgeu "branch greater or equal unsigned" ()
+ "bgeu $r0,$r1,$branch"
+ (+ OP_BGEU r0 r1 branch)
+ (if (geu r0 r1)
+ (set pc branch)
+ )
+ ()
+)
+
+(dni bgu "branch greater unsigned" ()
+ "bgu $r0,$r1,$branch"
+ (+ OP_BGU r0 r1 branch)
+ (if (gtu r0 r1)
+ (set pc branch)
+ )
+ ()
+)
+
+(dni bne "branch not equal" ()
+ "bne $r0,$r1,$branch"
+ (+ OP_BNE r0 r1 branch)
+ (if (ne r0 r1)
+ (set pc branch)
+ )
+ ()
+)
+
+(dni call "call" ()
+ "call $r0"
+ (+ OP_CALL r0 (f-r1 0) (f-r2 0) (f-resv0 0))
+ (sequence ()
+ (set (reg h-gr 29) (add pc 4))
+ (set pc r0)
+ )
+ ()
+)
+
+(dni calli "call immediate" ()
+ "calli $call"
+ (+ OP_CALLI call)
+ (sequence ()
+ (set (reg h-gr 29) (add pc 4))
+ (set pc (ext SI call))
+ )
+ ()
+)
+
+(dni cmpe "compare equal" ()
+ "cmpe $r2,$r0,$r1"
+ (+ OP_CMPE r0 r1 r2 (f-resv0 0))
+ (set r2 (eq SI r0 r1))
+ ()
+)
+
+(dni cmpei "compare equal immediate" ()
+ "cmpei $r1,$r0,$imm"
+ (+ OP_CMPEI r0 r1 imm)
+ (set r1 (eq SI r0 (ext SI (trunc HI imm))))
+ ()
+)
+
+(dni cmpg "compare greater than" ()
+ "cmpg $r2,$r0,$r1"
+ (+ OP_CMPG r0 r1 r2 (f-resv0 0))
+ (set r2 (gt SI r0 r1))
+ ()
+)
+
+(dni cmpgi "compare greater than immediate" ()
+ "cmpgi $r1,$r0,$imm"
+ (+ OP_CMPGI r0 r1 imm)
+ (set r1 (gt SI r0 (ext SI (trunc HI imm))))
+ ()
+)
+
+(dni cmpge "compare greater or equal" ()
+ "cmpge $r2,$r0,$r1"
+ (+ OP_CMPGE r0 r1 r2 (f-resv0 0))
+ (set r2 (ge SI r0 r1))
+ ()
+)
+
+(dni cmpgei "compare greater or equal immediate" ()
+ "cmpgei $r1,$r0,$imm"
+ (+ OP_CMPGEI r0 r1 imm)
+ (set r1 (ge SI r0 (ext SI (trunc HI imm))))
+ ()
+)
+
+(dni cmpgeu "compare greater or equal unsigned" ()
+ "cmpgeu $r2,$r0,$r1"
+ (+ OP_CMPGEU r0 r1 r2 (f-resv0 0))
+ (set r2 (geu SI r0 r1))
+ ()
+)
+
+(dni cmpgeui "compare greater or equal unsigned immediate" ()
+ "cmpgeui $r1,$r0,$uimm"
+ (+ OP_CMPGEUI r0 r1 uimm)
+ (set r1 (geu SI r0 (zext SI uimm)))
+ ()
+)
+
+(dni cmpgu "compare greater than unsigned" ()
+ "cmpgu $r2,$r0,$r1"
+ (+ OP_CMPGU r0 r1 r2 (f-resv0 0))
+ (set r2 (gtu SI r0 r1))
+ ()
+)
+
+(dni cmpgui "compare greater than unsigned immediate" ()
+ "cmpgui $r1,$r0,$uimm"
+ (+ OP_CMPGUI r0 r1 uimm)
+ (set r1 (gtu SI r0 (zext SI uimm)))
+ ()
+)
+
+(dni cmpne "compare not equal" ()
+ "cmpne $r2,$r0,$r1"
+ (+ OP_CMPNE r0 r1 r2 (f-resv0 0))
+ (set r2 (ne SI r0 r1))
+ ()
+)
+
+(dni cmpnei "compare not equal immediate" ()
+ "cmpnei $r1,$r0,$imm"
+ (+ OP_CMPNEI r0 r1 imm)
+ (set r1 (ne SI r0 (ext SI (trunc HI imm))))
+ ()
+)
+
+(dni divu "unsigned divide" ()
+ "divu $r2,$r0,$r1"
+ (+ OP_DIVU r0 r1 r2 (f-resv0 0))
+ (set pc (c-call USI "@cpu@_divu_insn" pc f-r0 f-r1 f-r2))
+ ()
+)
+
+(dni lb "load byte" ()
+ "lb $r1,($r0+$imm)"
+ (+ OP_LB r0 r1 imm)
+ (set r1 (ext SI (mem QI (add r0 (ext SI (trunc HI imm))))))
+ ()
+)
+
+(dni lbu "load byte unsigned" ()
+ "lbu $r1,($r0+$imm)"
+ (+ OP_LBU r0 r1 imm)
+ (set r1 (zext SI (mem QI (add r0 (ext SI (trunc HI imm))))))
+ ()
+)
+
+(dni lh "load halfword" ()
+ "lh $r1,($r0+$imm)"
+ (+ OP_LH r0 r1 imm)
+ (set r1 (ext SI (mem HI (add r0 (ext SI (trunc HI imm))))))
+ ()
+)
+
+(dni lhu "load halfword unsigned" ()
+ "lhu $r1,($r0+$imm)"
+ (+ OP_LHU r0 r1 imm)
+ (set r1 (zext SI (mem HI (add r0 (ext SI (trunc HI imm))))))
+ ()
+)
+
+(dni lw "load word" ()
+ "lw $r1,($r0+$imm)"
+ (+ OP_LW r0 r1 imm)
+ (set r1 (mem SI (add r0 (ext SI (trunc HI imm)))))
+ ()
+)
+
+(dni modu "unsigned modulus" ()
+ "modu $r2,$r0,$r1"
+ (+ OP_MODU r0 r1 r2 (f-resv0 0))
+ (set pc (c-call USI "@cpu@_modu_insn" pc f-r0 f-r1 f-r2))
+ ()
+)
+
+(dni mul "mulitply" ()
+ "mul $r2,$r0,$r1"
+ (+ OP_MUL r0 r1 r2 (f-resv0 0))
+ (set r2 (mul r0 r1))
+ ()
+)
+
+(dni muli "multiply immediate" ()
+ "muli $r1,$r0,$imm"
+ (+ OP_MULI r0 r1 imm)
+ (set r1 (mul r0 (ext SI (trunc HI imm))))
+ ()
+)
+
+(dni nor "nor" ()
+ "nor $r2,$r0,$r1"
+ (+ OP_NOR r0 r1 r2 (f-resv0 0))
+ (set r2 (inv (or r0 r1)))
+ ()
+)
+
+(dni nori "nor immediate" ()
+ "nori $r1,$r0,$uimm"
+ (+ OP_NORI r0 r1 uimm)
+ (set r1 (inv (or r0 (zext SI uimm))))
+ ()
+)
+
+(dni or "or" ()
+ "or $r2,$r0,$r1"
+ (+ OP_OR r0 r1 r2 (f-resv0 0))
+ (set r2 (or r0 r1))
+ ()
+)
+
+(dni ori "or immediate" ()
+ "ori $r1,$r0,$lo16"
+ (+ OP_ORI r0 r1 lo16)
+ (set r1 (or r0 (zext SI lo16)))
+ ()
+)
+
+(dni orhii "or high immediate" ()
+ "orhi $r1,$r0,$hi16"
+ (+ OP_ORHI r0 r1 hi16)
+ (set r1 (or r0 (sll SI hi16 16)))
+ ()
+)
+
+(dni rcsr "read control or status register" ()
+ "rcsr $r2,$csr"
+ (+ OP_RCSR csr (f-r1 0) r2 (f-resv0 0))
+ (set r2 csr)
+ ()
+)
+
+(dni sb "store byte" ()
+ "sb ($r0+$imm),$r1"
+ (+ OP_SB r0 r1 imm)
+ (set (mem QI (add r0 (ext SI (trunc HI imm)))) r1)
+ ()
+)
+
+(dni sextb "sign extend byte" ()
+ "sextb $r2,$r0"
+ (+ OP_SEXTB r0 (f-r1 0) r2 (f-resv0 0))
+ (set r2 (ext SI (trunc QI r0)))
+ ()
+)
+
+(dni sexth "sign extend half-word" ()
+ "sexth $r2,$r0"
+ (+ OP_SEXTH r0 (f-r1 0) r2 (f-resv0 0))
+ (set r2 (ext SI (trunc HI r0)))
+ ()
+)
+
+(dni sh "store halfword" ()
+ "sh ($r0+$imm),$r1"
+ (+ OP_SH r0 r1 imm)
+ (set (mem HI (add r0 (ext SI (trunc HI imm)))) r1)
+ ()
+)
+
+(dni sl "shift left" ()
+ "sl $r2,$r0,$r1"
+ (+ OP_SL r0 r1 r2 (f-resv0 0))
+ (set r2 (sll SI r0 r1))
+ ()
+)
+
+(dni sli "shift left immediate" ()
+ "sli $r1,$r0,$imm"
+ (+ OP_SLI r0 r1 imm)
+ (set r1 (sll SI r0 imm))
+ ()
+)
+
+(dni sr "shift right" ()
+ "sr $r2,$r0,$r1"
+ (+ OP_SR r0 r1 r2 (f-resv0 0))
+ (set r2 (sra SI r0 r1))
+ ()
+)
+
+(dni sri "shift right immediate" ()
+ "sri $r1,$r0,$imm"
+ (+ OP_SRI r0 r1 imm)
+ (set r1 (sra SI r0 imm))
+ ()
+)
+
+(dni sru "shift right unsigned" ()
+ "sru $r2,$r0,$r1"
+ (+ OP_SRU r0 r1 r2 (f-resv0 0))
+ (set r2 (srl SI r0 r1))
+ ()
+)
+
+(dni srui "shift right unsigned immediate" ()
+ "srui $r1,$r0,$imm"
+ (+ OP_SRUI r0 r1 imm)
+ (set r1 (srl SI r0 imm))
+ ()
+)
+
+(dni sub "subtract" ()
+ "sub $r2,$r0,$r1"
+ (+ OP_SUB r0 r1 r2 (f-resv0 0))
+ (set r2 (sub r0 r1))
+ ()
+)
+
+(dni sw "store word" ()
+ "sw ($r0+$imm),$r1"
+ (+ OP_SW r0 r1 imm)
+ (set (mem SI (add r0 (ext SI (trunc HI imm)))) r1)
+ ()
+)
+
+(dni user "user defined instruction" ()
+ "user $r2,$r0,$r1,$user"
+ (+ OP_USER r0 r1 r2 user)
+ (set r2 (c-call SI "@cpu@_user_insn" r0 r1 user))
+ ()
+)
+
+(dni wcsr "write control or status register" ()
+ "wcsr $csr,$r1"
+ (+ OP_WCSR csr r1 (f-r2 0) (f-resv0 0))
+ (c-call VOID "@cpu@_wcsr_insn" f-csr r1)
+ ()
+)
+
+(dni xor "xor" ()
+ "xor $r2,$r0,$r1"
+ (+ OP_XOR r0 r1 r2 (f-resv0 0))
+ (set r2 (xor r0 r1))
+ ()
+)
+
+(dni xori "xor immediate" ()
+ "xori $r1,$r0,$uimm"
+ (+ OP_XORI r0 r1 uimm)
+ (set r1 (xor r0 (zext SI uimm)))
+ ()
+)
+
+(dni xnor "xnor" ()
+ "xnor $r2,$r0,$r1"
+ (+ OP_XNOR r0 r1 r2 (f-resv0 0))
+ (set r2 (inv (xor r0 r1)))
+ ()
+)
+
+(dni xnori "xnor immediate" ()
+ "xnori $r1,$r0,$uimm"
+ (+ OP_XNORI r0 r1 uimm)
+ (set r1 (inv (xor r0 (zext SI uimm))))
+ ()
+)
+
+; Pseudo instructions
+
+(dni break "breakpoint" ()
+ "break"
+ (+ OP_RAISE (f-exception 2))
+ (set pc (c-call USI "@cpu@_break_insn" pc))
+ ()
+)
+
+(dni scall "system call" ()
+ "scall"
+ (+ OP_RAISE (f-exception 7))
+ (set pc (c-call USI "@cpu@_scall_insn" pc))
+ ()
+)
+
+(dni bret "return from breakpoint" (ALIAS)
+ "bret"
+ (+ OP_B (f-r0 31) (f-r1 0) (f-r2 0) (f-resv0 0))
+ (set pc (c-call USI "@cpu@_bret_insn" r0))
+ ()
+)
+
+(dni eret "return from exception" (ALIAS)
+ "eret"
+ (+ OP_B (f-r0 30) (f-r1 0) (f-r2 0) (f-resv0 0))
+ (set pc (c-call USI "@cpu@_eret_insn" r0))
+ ()
+)
+
+(dni ret "return" (ALIAS)
+ "ret"
+ (+ OP_B (f-r0 29) (f-r1 0) (f-r2 0) (f-resv0 0))
+ (set pc r0)
+ ()
+)
+
+(dni mv "move" (ALIAS)
+ "mv $r2,$r0"
+ (+ OP_OR r0 (f-r1 0) r2 (f-resv0 0))
+ (set r2 r0)
+ ()
+)
+
+(dni mvi "move immediate" (ALIAS)
+ "mvi $r1,$imm"
+ (+ OP_ADDI (f-r0 0) r1 imm)
+ (set r1 (add r0 (ext SI (trunc HI imm))))
+ ()
+)
+
+(dni mvui "move unsigned immediate" (ALIAS)
+ "mvu $r1,$lo16"
+ (+ OP_ORI (f-r0 0) r1 lo16)
+ (set r1 (zext SI lo16))
+ ()
+)
+
+(dni mvhi "move high immediate" (ALIAS)
+ "mvhi $r1,$hi16"
+ (+ OP_ORHI (f-r0 0) r1 hi16)
+ (set r1 (or r0 (sll SI hi16 16)))
+ ()
+)
+
+(dni mva "move address" (ALIAS)
+ "mva $r1,$gp16"
+ (+ OP_ADDI (f-r0 26) r1 gp16)
+ (set r1 (add r0 (ext SI (trunc HI gp16))))
+ ()
+)
+
+(dni not "not" (ALIAS)
+ "not $r2,$r0"
+ (+ OP_XNOR r0 (f-r1 0) r2 (f-resv0 0))
+ (set r2 (inv r0))
+ ()
+)
+
+(dni nop "nop" (ALIAS)
+ "nop"
+ (+ OP_ADDI (f-r0 0) (f-r1 0) (f-imm 0))
+ (set r0 r0)
+ ()
+)
+
+(dni lbgprel "load byte gp relative" (ALIAS)
+ "lb $r1,$gp16"
+ (+ OP_LB (f-r0 26) r1 gp16)
+ (set r1 (ext SI (mem QI (add r0 (ext SI (trunc HI gp16))))))
+ ()
+)
+
+(dni lbugprel "load byte unsigned gp relative" (ALIAS)
+ "lbu $r1,$gp16"
+ (+ OP_LBU (f-r0 26) r1 gp16)
+ (set r1 (zext SI (mem QI (add r0 (ext SI (trunc HI gp16))))))
+ ()
+)
+
+(dni lhgprel "load halfword gp relative" (ALIAS)
+ "lh $r1,$gp16"
+ (+ OP_LH (f-r0 26) r1 gp16)
+ (set r1 (ext SI (mem HI (add r0 (ext SI (trunc HI gp16))))))
+ ()
+)
+
+(dni lhugprel "load halfword unsigned gp relative" (ALIAS)
+ "lhu $r1,$gp16"
+ (+ OP_LHU (f-r0 26) r1 gp16)
+ (set r1 (zext SI (mem HI (add r0 (ext SI (trunc HI gp16))))))
+ ()
+)
+
+(dni lwgprel "load word gp relative" (ALIAS)
+ "lw $r1,$gp16"
+ (+ OP_LW (f-r0 26) r1 gp16)
+ (set r1 (mem SI (add r0 (ext SI (trunc HI gp16)))))
+ ()
+)
+
+(dni sbgprel "store byte gp relative" (ALIAS)
+ "sb $gp16,$r1"
+ (+ OP_SB (f-r0 26) r1 gp16)
+ (set (mem QI (add r0 (ext SI (trunc HI gp16)))) r1)
+ ()
+)
+
+(dni shgprel "store halfword gp relative" (ALIAS)
+ "sh $gp16,$r1"
+ (+ OP_SH (f-r0 26) r1 gp16)
+ (set (mem HI (add r0 (ext SI (trunc HI gp16)))) r1)
+ ()
+)
+
+(dni swgprel "store word gp relative" (ALIAS)
+ "sw $gp16,$r1"
+ (+ OP_SW (f-r0 26) r1 gp16)
+ (set (mem SI (add r0 (ext SI (trunc HI gp16)))) r1)
+ ()
+)
+
+(dni lwgotrel "load word got relative" (ALIAS)
+ "lw $r1,(gp+$got16)"
+ (+ OP_LW (f-r0 26) r1 got16)
+ (set r1 (mem SI (add r0 (ext SI (trunc HI got16)))))
+ ()
+)
+
+(dni orhigotoffi "or high got offset immediate" (ALIAS)
+ "orhi $r1,$r0,$gotoffhi16"
+ (+ OP_ORHI r0 r1 gotoffhi16)
+ (set r1 (or r0 (sll SI gotoffhi16 16)))
+ ()
+)
+
+(dni addgotoff "add got offset" (ALIAS)
+ "addi $r1,$r0,$gotofflo16"
+ (+ OP_ADDI r0 r1 gotofflo16)
+ (set r1 (add r0 (ext SI (trunc HI gotofflo16))))
+ ()
+)
+
+(dni swgotoff "store word got offset" (ALIAS)
+ "sw ($r0+$gotofflo16),$r1"
+ (+ OP_SW r0 r1 gotofflo16)
+ (set (mem SI (add r0 (ext SI (trunc HI gotofflo16)))) r1)
+ ()
+)
+
+(dni lwgotoff "load word got offset" (ALIAS)
+ "lw $r1,($r0+$gotofflo16)"
+ (+ OP_LW r0 r1 gotofflo16)
+ (set r1 (mem SI (add r0 (ext SI (trunc HI gotofflo16)))))
+ ()
+)
+
+(dni shgotoff "store half word got offset" (ALIAS)
+ "sh ($r0+$gotofflo16),$r1"
+ (+ OP_SH r0 r1 gotofflo16)
+ (set (mem HI (add r0 (ext SI (trunc HI gotofflo16)))) r1)
+ ()
+)
+
+(dni lhgotoff "load half word got offset" (ALIAS)
+ "lh $r1,($r0+$gotofflo16)"
+ (+ OP_LH r0 r1 gotofflo16)
+ (set r1 (ext SI (mem HI (add r0 (ext SI (trunc HI gotofflo16))))))
+ ()
+)
+
+(dni lhugotoff "load half word got offset unsigned" (ALIAS)
+ "lhu $r1,($r0+$gotofflo16)"
+ (+ OP_LHU r0 r1 gotofflo16)
+ (set r1 (zext SI (mem HI (add r0 (ext SI (trunc HI gotofflo16))))))
+ ()
+)
+
+(dni sbgotoff "store byte got offset" (ALIAS)
+ "sb ($r0+$gotofflo16),$r1"
+ (+ OP_SB r0 r1 gotofflo16)
+ (set (mem QI (add r0 (ext SI (trunc HI gotofflo16)))) r1)
+ ()
+)
+
+(dni lbgotoff "load byte got offset" (ALIAS)
+ "lb $r1,($r0+$gotofflo16)"
+ (+ OP_LB r0 r1 gotofflo16)
+ (set r1 (ext SI (mem QI (add r0 (ext SI (trunc HI gotofflo16))))))
+ ()
+)
+
+(dni lbugotoff "load byte got offset unsigned" (ALIAS)
+ "lbu $r1,($r0+$gotofflo16)"
+ (+ OP_LBU r0 r1 gotofflo16)
+ (set r1 (zext SI (mem QI (add r0 (ext SI (trunc HI gotofflo16))))))
+ ()
+)
diff --git a/cpu/lm32.opc b/cpu/lm32.opc
new file mode 100644
index 0000000000..cac75c1f24
--- /dev/null
+++ b/cpu/lm32.opc
@@ -0,0 +1,235 @@
+/* Lattice Mico32 opcode support. -*- C -*-
+ Copyright 2008 Free Software Foundation, Inc.
+ Contributed by Jon Beniston <jon@beniston.com>
+
+ This file is part of the GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* -- opc.h */
+
+/* Allows reason codes to be output when assembler errors occur. */
+#define CGEN_VERBOSE_ASSEMBLER_ERRORS
+
+#define CGEN_DIS_HASH_SIZE 64
+#define CGEN_DIS_HASH(buf,value) ((value >> 26) & 0x3f)
+
+/* -- asm.c */
+
+/* Handle signed/unsigned literal. */
+
+static const char *
+parse_imm (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ unsigned long *valuep)
+{
+ const char *errmsg;
+ signed long value;
+
+ errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
+ if (errmsg == NULL)
+ {
+ unsigned long x = value & 0xFFFF0000;
+ if (x != 0 && x != 0xFFFF0000)
+ errmsg = _("immediate value out of range");
+ else
+ *valuep = (value & 0xFFFF);
+ }
+ return errmsg;
+}
+
+/* Handle hi() */
+
+static const char *
+parse_hi16 (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ unsigned long *valuep)
+{
+ if (strncasecmp (*strp, "hi(", 3) == 0)
+ {
+ enum cgen_parse_operand_result result_type;
+ bfd_vma value;
+ const char *errmsg;
+
+ *strp += 3;
+ errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
+ &result_type, &value);
+ if (**strp != ')')
+ return _("missing `)'");
+
+ ++*strp;
+ if (errmsg == NULL
+ && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+ value = (value >> 16) & 0xffff;
+ *valuep = value;
+
+ return errmsg;
+ }
+
+ return parse_imm (cd, strp, opindex, valuep);
+}
+
+/* Handle lo() */
+
+static const char *
+parse_lo16 (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ unsigned long *valuep)
+{
+ if (strncasecmp (*strp, "lo(", 3) == 0)
+ {
+ const char *errmsg;
+ enum cgen_parse_operand_result result_type;
+ bfd_vma value;
+
+ *strp += 3;
+ errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
+ &result_type, &value);
+ if (**strp != ')')
+ return _("missing `)'");
+ ++*strp;
+ if (errmsg == NULL
+ && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+ value &= 0xffff;
+ *valuep = value;
+ return errmsg;
+ }
+
+ return parse_imm (cd, strp, opindex, valuep);
+}
+
+/* Handle gp() */
+
+static const char *
+parse_gp16 (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ long *valuep)
+{
+ if (strncasecmp (*strp, "gp(", 3) == 0)
+ {
+ const char *errmsg;
+ enum cgen_parse_operand_result result_type;
+ bfd_vma value;
+
+ *strp += 3;
+ errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_GPREL16,
+ & result_type, & value);
+ if (**strp != ')')
+ return _("missing `)'");
+ ++*strp;
+ if (errmsg == NULL
+ && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+ value &= 0xffff;
+ *valuep = value;
+ return errmsg;
+ }
+
+ return _("expecting gp relative address: gp(symbol)");
+}
+
+/* Handle got() */
+
+static const char *
+parse_got16 (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ long *valuep)
+{
+ if (strncasecmp (*strp, "got(", 4) == 0)
+ {
+ const char *errmsg;
+ enum cgen_parse_operand_result result_type;
+ bfd_vma value;
+
+ *strp += 4;
+ errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_16_GOT,
+ & result_type, & value);
+ if (**strp != ')')
+ return _("missing `)'");
+ ++*strp;
+ if (errmsg == NULL
+ && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+ value &= 0xffff;
+ *valuep = value;
+ return errmsg;
+ }
+
+ return _("expecting got relative address: got(symbol)");
+}
+
+/* Handle gotoffhi16() */
+
+static const char *
+parse_gotoff_hi16 (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ long *valuep)
+{
+ if (strncasecmp (*strp, "gotoffhi16(", 11) == 0)
+ {
+ const char *errmsg;
+ enum cgen_parse_operand_result result_type;
+ bfd_vma value;
+
+ *strp += 11;
+ errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_GOTOFF_HI16,
+ & result_type, & value);
+ if (**strp != ')')
+ return _("missing `)'");
+ ++*strp;
+ if (errmsg == NULL
+ && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+ value &= 0xffff;
+ *valuep = value;
+ return errmsg;
+ }
+
+ return _("expecting got relative address: gotoffhi16(symbol)");
+}
+
+/* Handle gotofflo16() */
+
+static const char *
+parse_gotoff_lo16 (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ long *valuep)
+{
+ if (strncasecmp (*strp, "gotofflo16(", 11) == 0)
+ {
+ const char *errmsg;
+ enum cgen_parse_operand_result result_type;
+ bfd_vma value;
+
+ *strp += 11;
+ errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_GOTOFF_LO16,
+ &result_type, &value);
+ if (**strp != ')')
+ return _("missing `)'");
+ ++*strp;
+ if (errmsg == NULL
+ && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+ value &= 0xffff;
+ *valuep = value;
+ return errmsg;
+ }
+
+ return _("expecting got relative address: gotofflo16(symbol)");
+}