diff options
Diffstat (limited to 'cpu')
-rw-r--r-- | cpu/ChangeLog | 5 | ||||
-rw-r--r-- | cpu/lm32.cpu | 932 | ||||
-rw-r--r-- | cpu/lm32.opc | 235 |
3 files changed, 1172 insertions, 0 deletions
diff --git a/cpu/ChangeLog b/cpu/ChangeLog index 707c585..671bc11 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 0000000..cf82615 --- /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 0000000..cac75c1 --- /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)"); +} |