diff options
author | Jim Meyering <meyering@redhat.com> | 2009-10-08 08:50:51 +0000 |
---|---|---|
committer | Jim Meyering <meyering@redhat.com> | 2009-10-08 08:58:19 +0000 |
commit | 79b5a82e464c9ec7731ed6f80580ceb13f745168 (patch) | |
tree | e258911599426e00b8bc17b4e491a583c9d88027 /cpu | |
parent | f699d949b3eb15dfba4284d326934d5163fc444b (diff) | |
download | gdb-79b5a82e464c9ec7731ed6f80580ceb13f745168.tar.gz |
manually sync from the CVS repository
Diffstat (limited to 'cpu')
-rw-r--r-- | cpu/ChangeLog | 707 | ||||
-rw-r--r-- | cpu/cris.cpu | 4553 | ||||
-rw-r--r-- | cpu/frv.cpu | 9799 | ||||
-rw-r--r-- | cpu/frv.opc | 1918 | ||||
-rw-r--r-- | cpu/iq10.cpu | 1112 | ||||
-rw-r--r-- | cpu/iq2000.cpu | 1196 | ||||
-rw-r--r-- | cpu/iq2000.opc | 320 | ||||
-rw-r--r-- | cpu/iq2000m.cpu | 631 | ||||
-rw-r--r-- | cpu/lm32.cpu | 932 | ||||
-rw-r--r-- | cpu/lm32.opc | 235 | ||||
-rw-r--r-- | cpu/m32c.cpu | 10520 | ||||
-rw-r--r-- | cpu/m32c.opc | 1187 | ||||
-rw-r--r-- | cpu/m32r.cpu | 2427 | ||||
-rw-r--r-- | cpu/m32r.opc | 324 | ||||
-rw-r--r-- | cpu/mt.cpu | 1352 | ||||
-rw-r--r-- | cpu/mt.opc | 472 | ||||
-rw-r--r-- | cpu/sh.cpu | 369 | ||||
-rw-r--r-- | cpu/sh.opc | 77 | ||||
-rw-r--r-- | cpu/sh64-compact.cpu | 1748 | ||||
-rw-r--r-- | cpu/sh64-media.cpu | 1733 | ||||
-rw-r--r-- | cpu/simplify.inc | 218 | ||||
-rw-r--r-- | cpu/xc16x.cpu | 3127 | ||||
-rw-r--r-- | cpu/xc16x.opc | 245 |
23 files changed, 45202 insertions, 0 deletions
diff --git a/cpu/ChangeLog b/cpu/ChangeLog new file mode 100644 index 00000000000..2b8c45a4545 --- /dev/null +++ b/cpu/ChangeLog @@ -0,0 +1,707 @@ +2009-09-25 Alan Modra <amodra@bigpond.net.au> + + * m32r.cpu (stb-plus): Typo fix. + +2009-09-23 Doug Evans <dje@sebabeach.org> + + * m32r.cpu (sth-plus): Fix address mode and calculation. + (stb-plus): Ditto. + (clrpsw): Fix mask calculation. + (bset, bclr, btst): Make mode in bit calculation match expression. + + * xc16x.cpu (rtl-version): Set to 0.8. + (gr-names, ext-names,psw-names): Update, print-name -> enum-prefix, + make uppercase. Remove unnecessary name-prefix spec. + (grb-names, conditioncode-names, extconditioncode-names): Ditto. + (grb8-names, r8-names, regmem8-names, regdiv8-names): Ditto. + (reg0-name, reg0-name1, regbmem8-names, memgr8-names): Ditto. + (h-cr): New hardware. + (muls): Comment out parts that won't compile, add fixme. + (mulu, divl, divlu, jmpabs, jmpa-, jmprel, jbc, jnbs, callr): Ditto. + (scxti, scxtmg, scxtm, bclear, bclr18, bset19, bitset, bmov): Ditto. + (bmovn, band, bor, bxor, bcmp, bfldl, bfldh): Ditto. + +2009-07-16 Doug Evans <dje@sebabeach.org> + + * cpu/simplify.inc (*): One line doc strings don't need \n. + (df): Invoke define-full-ifield instead of claiming it's an alias. + (dno): Define. + (dnop): Mark as deprecated. + +2009-06-22 Alan Modra <amodra@bigpond.net.au> + + * m32c.opc (parse_lab_5_3): Use correct enum. + +2009-01-07 Hans-Peter Nilsson <hp@axis.com> + + * frv.cpu (mabshs): Explicitly sign-extend arguments of abs to DI. + (DI-ext-HI, DI-ext-UHI, DI-ext-DI): New pmacros. + (media-arith-sat-semantics): Explicitly sign- or zero-extend + arguments of "operation" to DI using "mode" and the new pmacros. + +2009-01-03 Hans-Peter Nilsson <hp@axis.com> + + * cris.cpu (cris-implemented-writable-specregs-v32): Correct size + of number 2, PID. + +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 + to source. + +2007-10-22 Hans-Peter Nilsson <hp@axis.com> + + * cris.cpu (movs, movu): Use result of extension operation when + updating flags. + +2007-07-04 Nick Clifton <nickc@redhat.com> + + * cris.cpu: Update copyright notice to refer to GPLv3. + * frv.cpu, frv.opc, iq10.cpu, iq2000m.cpu, iq2000.opc, m32c.cpu, + m32c.opc, m32r.cpu, m32r.opc, mt.cpu, mt.opc, sh64-compact.cpu, + sh64-media.cpu, sh.cpu, sh.opc, simplify.inc, xc16x.cpu, + xc16x.opc: Likewise. + * iq2000.cpu: Fix copyright notice to refer to FSF. + +2007-04-30 Mark Salter <msalter@sadr.localdomain> + + * frv.cpu (spr-names): Support new coprocessor SPR registers. + +2007-04-20 Nick Clifton <nickc@redhat.com> + + * xc16x.cpu: Restore after accidentally overwriting this file with + xc16x.opc. + +2007-03-29 DJ Delorie <dj@redhat.com> + + * m32c.cpu (Imm-8-s4n): Fix print hook. + (Lab-24-8, Lab-32-8, Lab-40-8): Fix. + (arith-jnz-imm4-dst-defn): Make relaxable. + (arith-jnz16-imm4-dst-defn): Fix encodings. + +2007-03-20 DJ Delorie <dj@redhat.com> + + * m32c.cpu (f-dsp-40-u20, f-dsp-48-u20, Dsp-40-u20, Dsp-40-u20, + mem20): New. + (src16-16-20-An-relative-*): New. + (dst16-*-20-An-relative-*): New. + (dst16-16-16sa-*): New + (dst16-16-16ar-*): New + (dst32-16-16sa-Unprefixed-*): New + (jsri): Fix operands. + (setzx): Fix encoding. + +2007-03-08 Alan Modra <amodra@bigpond.net.au> + + * m32r.opc: Formatting. + +2006-05-22 Nick Clifton <nickc@redhat.com> + + * iq2000.cpu: Fix include paths for iq2000m.cpu and iq10.cpu. + +2006-04-10 DJ Delorie <dj@redhat.com> + + * m32c.opc (parse_unsigned_bitbase): Take a new parameter which + decides if this function accepts symbolic constants or not. + (parse_signed_bitbase): Likewise. + (parse_unsigned_bitbase8): Pass the new parameter. + (parse_unsigned_bitbase11): Likewise. + (parse_unsigned_bitbase16): Likewise. + (parse_unsigned_bitbase19): Likewise. + (parse_unsigned_bitbase27): Likewise. + (parse_signed_bitbase8): Likewise. + (parse_signed_bitbase11): Likewise. + (parse_signed_bitbase19): Likewise. + +2006-03-13 DJ Delorie <dj@redhat.com> + + * m32c.cpu (Bit3-S): New. + (btst:s): New. + * m32c.opc (parse_bit3_S): New. + + * m32c.cpu (decimal-subtraction16-insn): Add second operand. + (btst): Add optional :G suffix for MACH32. + (or.b:S): New. + (pop.w:G): Add optional :G suffix for MACH16. + (push.b.imm): Fix syntax. + +2006-03-10 DJ Delorie <dj@redhat.com> + + * m32c.cpu (mul.l): New. + (mulu.l): New. + +2006-03-03 Shrirang Khisti <shrirangk@kpitcummins.com) + + * xc16x.opc (parse_hash): Return NULL if the input was parsed or + an error message otherwise. + (parse_dot, parse_pof, parse_pag, parse_sof, parse_seg): Likewise. + Fix up comments to correctly describe the functions. + +2006-02-24 DJ Delorie <dj@redhat.com> + + * m32c.cpu (RL_TYPE): New attribute, with macros. + (Lab-8-24): Add RELAX. + (unary-insn-defn-g, binary-arith-imm-dst-defn, + binary-arith-imm4-dst-defn): Add 1ADDR attribute. + (binary-arith-src-dst-defn): Add 2ADDR attribute. + (jcnd16-5, jcnd16, jcnd32, jmp16.s, jmp16.b, jmp16.w, jmp16.a, + jmp32.s, jmp32.b, jmp32.w, jmp32.a, jsr16.w, jsr16.a): Add JUMP + attribute. + (jsri16, jsri32): Add 1ADDR attribute. + (jsr32.w, jsr32.a): Add JUMP attribute. + +2006-02-17 Shrirang Khisti <shrirangk@kpitcummins.com> + Anil Paranjape <anilp1@kpitcummins.com> + Shilin Shakti <shilins@kpitcummins.com> + + * xc16x.cpu: New file containing complete CGEN specific XC16X CPU + description. + * xc16x.opc: New file containing supporting XC16C routines. + +2006-02-10 Nick Clifton <nickc@redhat.com> + + * iq2000.opc (parse_hi16): Truncate shifted values to 16 bits. + +2006-01-06 DJ Delorie <dj@redhat.com> + + * m32c.cpu (mov.w:q): Fix mode. + (push32.b.imm): Likewise, for the comment. + +2005-12-16 Nathan Sidwell <nathan@codesourcery.com> + + Second part of ms1 to mt renaming. + * mt.cpu (define-arch, define-isa): Set name to mt. + (define-mach): Adjust. + * mt.opc (CGEN_ASM_HASH): Update. + (mt_asm_hash, mt_cgen_insn_supported): Renamed. + (parse_loopsize, parse_imm16): Adjust. + +2005-12-13 DJ Delorie <dj@redhat.com> + + * m32c.cpu (jsri): Fix order so register names aren't treated as + symbols. + (indexb, indexbd, indexbs, indexl, indexld, indexls, indexw, + indexwd, indexws): Fix encodings. + +2005-12-12 Nathan Sidwell <nathan@codesourcery.com> + + * mt.cpu: Rename from ms1.cpu. + * mt.opc: Rename from ms1.opc. + +2005-12-06 Hans-Peter Nilsson <hp@axis.com> + + * cris.cpu (simplecris-common-writable-specregs) + (simplecris-common-readable-specregs): Split from + simplecris-common-specregs. All users changed. + (cris-implemented-writable-specregs-v0) + (cris-implemented-readable-specregs-v0): Similar from + cris-implemented-specregs-v0. + (cris-implemented-writable-specregs-v3) + (cris-implemented-readable-specregs-v3) + (cris-implemented-writable-specregs-v8) + (cris-implemented-readable-specregs-v8) + (cris-implemented-writable-specregs-v10) + (cris-implemented-readable-specregs-v10) + (cris-implemented-writable-specregs-v32) + (cris-implemented-readable-specregs-v32): Similar. + (bdap-32-pc, move-m-pcplus-p0, move-m-spplus-p8): New + insns and specializations. + +2005-11-08 Nathan Sidwell <nathan@codesourcery.com> + + Add ms2 + * ms1.cpu (ms2, ms2bf): New architecture variant, cpu, machine and + model. + (f-uu8, f-uu1, f-imm16l, f-loopo, f-cb1sel, f-cb2sel, f-cb1incr, + f-cb2incr, f-rc3): New fields. + (LOOP): New instruction. + (JAL-HAZARD): New hazard. + (imm16o, loopsize, imm16l, rc3, cb1sel, cb2sel, cb1incr, cb2incr): + New operands. + (mul, muli, dbnz, iflush): Enable for ms2 + (jal, reti): Has JAL-HAZARD. + (ldctxt, ldfb, stfb): Only ms1. + (fbcb): Only ms1,ms1-003. + (wfbinc, mefbinc, wfbincr, mwfbincr, fbcbincs, mfbcbincs, + fbcbincrs, mfbcbincrs): Enable for ms2. + (loop, loopu, dfbc, dwfb, fbwfb, dfbr): New ms2 insns. + * ms1.opc (parse_loopsize): New. + (parse_imm16): hi16/lo16 relocs are applicable to IMM16L. + (print_pcrel): New. + +2005-10-28 Dave Brolley <brolley@redhat.com> + + Contribute the following change: + 2003-09-24 Dave Brolley <brolley@redhat.com> + + * frv.opc: Use CGEN_ATTR_VALUE_ENUM_TYPE in place of + CGEN_ATTR_VALUE_TYPE. + * m32c.opc (m32c_cgen_insn_supported): Use CGEN_INSN_BITSET_ATTR_VALUE. + Use cgen_bitset_intersect_p. + +2005-10-27 DJ Delorie <dj@redhat.com> + + * m32c.cpu (Imm-8-s4n, Imm-12-s4n): New. + (arith-jnz16-imm4-dst-defn, arith-jnz32-imm4-dst-defn, + arith-jnz-imm4-dst-mach, arith-jnz-imm4-dst): Keep track of which + imm operand is needed. + (adjnz, sbjnz): Pass the right operands. + (unary-insn-defn, unary16-defn, unary32-defn, unary-insn-mach, + unary-insn): Add -g variants for opcodes that need to support :G. + (not.BW:G, push.BW:G): Call it. + (stzx16-imm8-imm8-dsp8sb, stzx16-imm8-imm8-dsp8fb, + stzx16-imm8-imm8-abs16): Fix operand typos. + * m32c.opc (m32c_asm_hash): Support bnCND. + (parse_signed4n, print_signed4n): New. + +2005-10-26 DJ Delorie <dj@redhat.com> + + * m32c.cpu (f-dsp-8-s24, Dsp-8-s24): New. + (mov-dspsp-dst-defn, mov-src-dspsp-defn, mov16-dspsp-dst-defn, + mov16-src-dspsp-defn, mov32-dspsp-dst-defn, mov32-src-dspsp-defn): + dsp8[sp] is signed. + (mov.WL:S #imm,A0/A1): dsp24 is signed (i.e. -0x800000..0xffffff). + (mov.BW:S r0,r1): Fix typo r1l->r1. + (tst): Allow :G suffix. + * m32c.opc (parse_signed24): New, for -0x800000..0xffffff. + +2005-10-26 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com> + + * m32r.opc (parse_hi16): Do not assume a 32-bit host word size. + +2005-10-25 DJ Delorie <dj@redhat.com> + + * m32c.cpu (add16-bQ-sp,add16-wQ-sp): Fix to allow either width by + making one a macro of the other. + +2005-10-21 DJ Delorie <dj@redhat.com> + + * m32c.cpu (lde, ste): Add dsp[a0] and [a1a] addressing. + (indexb, indexbd, indexbs, indexw, indexwd, indexws, indexl, + indexld, indexls): .w variants have `1' bit. + (rot32.b): QI, not SI. + (rot32.w): HI, not SI. + (xchg16): HI for .w variant. + +2005-10-19 Nick Clifton <nickc@redhat.com> + + * m32r.opc (parse_slo16): Fix bad application of previous patch. + +2005-10-18 Andreas Schwab <schwab@suse.de> + + * m32r.opc (parse_slo16): Better version of previous patch. + +2005-10-14 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com> + + * cpu/m32r.opc (parse_slo16): Do not assume a 32-bit host word + size. + +2005-07-25 DJ Delorie <dj@redhat.com> + + * m32c.opc (parse_unsigned8): Add %dsp8(). + (parse_signed8): Add %hi8(). + (parse_unsigned16): Add %dsp16(). + (parse_signed16): Add %lo16() and %hi16(). + (parse_lab_5_3): Make valuep a bfd_vma *. + +2005-07-18 Nick Clifton <nickc@redhat.com> + + * m32c.cpu (f-16-8, f-24-8, f-32-16, f-dsp-8-u24): New opcode + components. + (f-lab32-jmp-s): Fix insertion sequence. + (Dsp-8-u24, Lab-5-3, Lab32-jmp-s): New operands. + (Dsp-40-s8): Make parameter be signed. + (Dsp-40-s16): Likewise. + (Dsp-48-s8): Likewise. + (Dsp-48-s16): Likewise. + (Imm-13-u3): Likewise. (Despite its name!) + (BitBase16-16-s8): Make the parameter be unsigned. + (BitBase16-8-u11-S): Likewise. + (Lab-8-8, Lab-8-16, Lab-16-8, jcnd16-5, jcnd16, jcnd32, jmp16.s, + jmp16.b, jmp16.w, jmp32.s, jmp32.b, jmp32.w, jsp16.w, jsr32.w): Allow + relaxation. + + * m32c.opc: Fix formatting. + Use safe-ctype.h instead of ctype.h + Move duplicated code sequences into a macro. + Fix compile time warnings about signedness mismatches. + Remove dead code. + (parse_lab_5_3): New parser function. + +2005-07-16 Jim Blandy <jimb@redhat.com> + + * m32c.opc (m32c_cgen_insn_supported): Use int, not CGEN_BITSET, + to represent isa sets. + +2005-07-15 Jim Blandy <jimb@redhat.com> + + * m32c.cpu, m32c.opc: Fix copyright. + +2005-07-14 Jim Blandy <jimb@redhat.com> + + * m32c.cpu, m32c.opc: Machine description for the Renesas M32C. + +2005-07-14 Alan Modra <amodra@bigpond.net.au> + + * ms1.opc (print_dollarhex): Correct format string. + +2005-07-06 Alan Modra <amodra@bigpond.net.au> + + * iq2000.cpu: Include from binutils cpu dir. + +2005-07-05 Nick Clifton <nickc@redhat.com> + + * iq2000.opc (parse_lo16, parse_mlo16): Make value parameter + unsigned in order to avoid compile time warnings about sign + conflicts. + + * ms1.opc (parse_*): Likewise. + (parse_imm16): Use a "void *" as it is passed both signed and + unsigned arguments. + +2005-07-01 Nick Clifton <nickc@redhat.com> + + * frv.opc: Update to ISO C90 function declaration style. + * iq2000.opc: Likewise. + * m32r.opc: Likewise. + * sh.opc: Likewise. + +2005-06-15 Dave Brolley <brolley@redhat.com> + + Contributed by Red Hat. + * ms1.cpu: New file. Written by Nick Clifton, Stan Cox. + * ms1.opc: New file. Written by Stan Cox. + +2005-05-10 Nick Clifton <nickc@redhat.com> + + * Update the address and phone number of the FSF organization in + the GPL notices in the following files: + cris.cpu, frv.cpu, frv.opc, iq10.cpu, iq2000.opc, iq2000m.cpu, + m32r.cpu, m32r.opc, sh.cpu, sh.opc, sh64-compact.cpu, + sh64-media.cpu, simplify.inc + +2005-02-24 Alan Modra <amodra@bigpond.net.au> + + * frv.opc (parse_A): Warning fix. + +2005-02-23 Nick Clifton <nickc@redhat.com> + + * frv.opc: Fixed compile time warnings about differing signed'ness + of pointers passed to functions. + * m32r.opc: Likewise. + +2005-02-11 Nick Clifton <nickc@redhat.com> + + * iq2000.opc (parse_jtargq10): Change type of valuep argument to + 'bfd_vma *' in order avoid compile time warning message. + +2005-01-28 Hans-Peter Nilsson <hp@axis.com> + + * cris.cpu (mstep): Add missing insn. + +2005-01-25 Alexandre Oliva <aoliva@redhat.com> + + 2004-11-10 Alexandre Oliva <aoliva@redhat.com> + * frv.cpu: Add support for TLS annotations in loads and calll. + * frv.opc (parse_symbolic_address): New. + (parse_ldd_annotation): New. + (parse_call_annotation): New. + (parse_ld_annotation): New. + (parse_ulo16, parse_uslo16): Use parse_symbolic_address. + Introduce TLS relocations. + (parse_d12, parse_s12, parse_u12): Likewise. + (parse_uhi16): Likewise. Fix constant checking on 64-bit host. + (parse_call_label, print_at): New. + +2004-12-21 Mikael Starvik <starvik@axis.com> + + * cris.cpu (cris-set-mem): Correct integral write semantics. + +2004-11-29 Hans-Peter Nilsson <hp@axis.com> + + * cris.cpu: New file. + +2004-11-15 Michael K. Lechner <mike.lechner@gmail.com> + + * iq2000.cpu: Added quotes around macro arguments so that they + will work with newer versions of guile. + +2004-10-27 Nick Clifton <nickc@redhat.com> + + * iq2000m.cpu (pkrlr1, pkrlr30, rbr1, rbr30, rxr1, rxr30, wbr1, + wbr1u, wbr30, wbr30u, wxr1, wxr1u, wxr30, wxr30u): Add an index + operand. + * iq2000.cpu (dnop index): Rename to _index to avoid complications + with guile. + +2004-08-27 Richard Sandiford <rsandifo@redhat.com> + + * frv.cpu (cfmovs): Change UNIT attribute to FMALL. + +2004-05-15 Nick Clifton <nickc@redhat.com> + + * iq2000.opc (iq2000_cgen_insn_supported): Make 'insn' argument const. + +2004-03-30 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com> + + * m32r.opc (parse_hi16): Fixed shigh(0xffff8000) bug. + +2004-03-01 Richard Sandiford <rsandifo@redhat.com> + + * frv.cpu (define-arch frv): Add fr450 mach. + (define-mach fr450): New. + (define-model fr450): New. Add profile units to every fr450 insn. + (define-attr UNIT): Add MDCUTSSI. + (define-attr FR450-MAJOR): New enum. Add to every fr450 insn. + (define-attr AUDIO): New boolean. + (f-LRAE, f-LRAD, f-LRAS, f-TLBPRopx, f-TLBPRL) + (f-LRA-null, f-TLBPR-null): New fields. + (scr0, scr1, scr2, scr3, imavr1, damvr1, cxnr, ttbr) + (tplr, tppr, tpxr, timerh, timerl, timerd, btbr): New SPRs. + (LRAE, LRAD, LRAS, TLBPRopx, TLBPRL): New operands. + (LRA-null, TLBPR-null): New macros. + (iacc-multiply-r-r, slass, scutss, int-arith-ss-r-r): Add AUDIO attr. + (load-real-address): New macro. + (lrai, lrad, tlbpr): New instructions. + (media-cut-acc, media-cut-acc-ss): Add fr450-major argument. + (mcut, mcuti, mcutss, mcutssi): Adjust accordingly. + (mdcutssi): Change UNIT attribute to MDCUTSSI. + (media-low-clear-semantics, media-scope-limit-semantics) + (media-quad-limit, media-quad-shift): New macros. + (mqlclrhs, mqlmths, mqsllhi, mqsrahi): New instructions. + * frv.opc (frv_is_branch_major, frv_is_float_major, frv_is_media_major) + (frv_is_branch_insn, frv_is_float_insn, frv_is_media_insn) + (frv_vliw_reset, frv_vliw_add_insn): Handle bfd_mach_fr450. + (fr450_unit_mapping): New array. + (fr400_unit_mapping, fr500_unit_mapping, fr550_unit_mapping): Add entry + for new MDCUTSSI unit. + (fr450_check_insn_major_constraints): New function. + (check_insn_major_constraints): Use it. + +2004-03-01 Richard Sandiford <rsandifo@redhat.com> + + * frv.cpu (nsdiv, nudiv, nsdivi, nudivi): Remove fr400 profiling unit. + (scutss): Change unit to I0. + (calll, callil, ccalll): Add missing FR550-MAJOR and profile unit. + (mqsaths): Fix FR400-MAJOR categorization. + (media-quad-multiply-cross-acc, media-quad-cross-multiply-cross-acc) + (media-quad-cross-multiply-acc): Change unit from MDUALACC to FMALL. + * frv.opc (fr400_check_insn_major_constraints): Check for (M-2,M-1) + combinations. + +2004-03-01 Richard Sandiford <rsandifo@redhat.com> + + * frv.cpu (r-store, r-store-dual, r-store-quad): Delete. + (rstb, rsth, rst, rstd, rstq): Delete. + (rstbf, rsthf, rstf, rstdf, rstqf): Delete. + +2004-02-23 Nick Clifton <nickc@redhat.com> + + * Apply these patches from Renesas: + + 2004-02-10 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com> + + * cpu/m32r.opc (my_print_insn): Fixed incorrect output when + disassembling codes for 0x*2 addresses. + + 2003-12-15 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com> + + * cpu/m32r.cpu: Add PIPE_O attribute to "pop" instruction. + + 2003-12-03 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com> + + * cpu/m32r.cpu : Add new model m32r2. + Add new instructions. + Replace occurrances of 'Mitsubishi' with 'Renesas'. + Changed PIPE attr of push from O to OS. + Care for Little-endian of M32R. + * cpu/m32r.opc (CGEN_DIS_HASH, my_print_insn): + Care for Little-endian of M32R. + (parse_slo16): signed extension for value. + +2004-02-20 Andrew Cagney <cagney@redhat.com> + + * m32r.opc, m32r.cpu: New files. Written by , Doug Evans, Nick + Clifton, Ben Elliston, Matthew Green, and Andrew Haley. + + * sh.cpu, sh.opc, sh64-compact.cpu, sh64-media.cpu: New files, all + written by Ben Elliston. + +2004-01-14 Richard Sandiford <rsandifo@redhat.com> + + * frv.cpu (UNIT): Add IACC. + (iacc-multiply-r-r): Use it. + * frv.opc (fr400_unit_mapping): Add entry for IACC. + (fr500_unit_mapping, fr550_unit_mapping): Likewise. + +2004-01-06 Alexandre Oliva <aoliva@redhat.com> + + 2003-12-19 Alexandre Oliva <aoliva@redhat.com> + * frv.opc (parse_ulo16, parse_uhi16, parse_d12): Fix some + cut&paste errors in shifting/truncating numerical operands. + 2003-08-08 Alexandre Oliva <aoliva@redhat.com> + * frv.opc (parse_ulo16): Parse gotofflo and gotofffuncdesclo. + (parse_uslo16): Likewise. + (parse_uhi16): Parse gotoffhi and gotofffuncdeschi. + (parse_d12): Parse gotoff12 and gotofffuncdesc12. + (parse_s12): Likewise. + 2003-08-04 Alexandre Oliva <aoliva@redhat.com> + * frv.opc (parse_ulo16): Parse gotlo and gotfuncdesclo. + (parse_uslo16): Likewise. + (parse_uhi16): Parse gothi and gotfuncdeschi. + (parse_d12): Parse got12 and gotfuncdesc12. + (parse_s12): Likewise. + +2003-10-10 Dave Brolley <brolley@redhat.com> + + * frv.cpu (dnpmop): New p-macro. + (GRdoublek): Use dnpmop. + (CPRdoublek, FRdoublei, FRdoublej, FRdoublek): Ditto. + (store-double-r-r): Use (.sym regtype doublek). + (r-store-double): Ditto. + (store-double-r-r-u): Ditto. + (conditional-store-double): Ditto. + (conditional-store-double-u): Ditto. + (store-double-r-simm): Ditto. + (fmovs): Assign to UNIT FMALL. + +2003-10-06 Dave Brolley <brolley@redhat.com> + + * frv.cpu, frv.opc: Add support for fr550. + +2003-09-24 Dave Brolley <brolley@redhat.com> + + * frv.cpu (u-commit): New modelling unit for fr500. + (mwtaccg): Use frv_ref_SI to reference ACC40Sk as an input operand. + (commit-r): Use u-commit model for fr500. + (commit): Ditto. + (conditional-float-binary-op): Take profiling data as an argument. + Update callers. + (ne-float-binary-op): Ditto. + +2003-09-19 Michael Snyder <msnyder@redhat.com> + + * frv.cpu (nldqi): Delete unimplemented instruction. + +2003-09-12 Dave Brolley <brolley@redhat.com> + + * frv.cpu (u-clrgr, u-clrfr): New units of model fr500. + (clear-ne-flag-r): Pass insn profiling in as an argument. Call + frv_ref_SI to get input register referenced for profiling. + (clear-ne-flag-all): Pass insn profiling in as an argument. + (clrgr,clrfr,clrga,clrfa): Add profiling information. + +2003-09-11 Michael Snyder <msnyder@redhat.com> + + * frv.cpu: Typographical corrections. + +2003-09-09 Dave Brolley <brolley@redhat.com> + + * frv.cpu (media-dual-complex): Change UNIT to FMALL. + (conditional-media-dual-complex, media-quad-complex): Likewise. + +2003-09-04 Dave Brolley <brolley@redhat.com> + + * frv.cpu (register-transfer): Pass in all attributes in on argument. + Update all callers. + (conditional-register-transfer): Ditto. + (cache-preload): Ditto. + (floating-point-conversion): Ditto. + (floating-point-neg): Ditto. + (float-abs): Ditto. + (float-binary-op-s): Ditto. + (conditional-float-binary-op): Ditto. + (ne-float-binary-op): Ditto. + (float-dual-arith): Ditto. + (ne-float-dual-arith): Ditto. + +2003-09-03 Dave Brolley <brolley@redhat.com> + + * frv.opc (parse_A, parse_A0, parse_A1): New parse handlers. + * frv.cpu (UNIT): Add IALL, FMALL, FMLOW, STORE, SCAN, DCPL, MDUALACC, + MCLRACC-1. + (A): Removed operand. + (A0,A1): New operands replace operand A. + (mnop): Now a real insn + (mclracc): Removed insn. + (mclracc-0, mclracc-1): New insns replace mclracc. + (all insns): Use new UNIT attributes. + +2003-08-21 Nick Clifton <nickc@redhat.com> + + * frv.cpu (mbtoh): Replace input parameter to u-media-dual-expand + and u-media-dual-btoh with output parameter. + (cmbtoh): Add profiling hack. + +2003-08-19 Michael Snyder <msnyder@redhat.com> + + * frv.cpu: Fix typo, Frintkeven -> FRintkeven + +2003-06-10 Doug Evans <dje@sebabeach.org> + + * frv.cpu: Add IDOC attribute. + +2003-06-06 Andrew Cagney <cagney@redhat.com> + + Contributed by Red Hat. + * iq2000.cpu: New file. Written by Ben Elliston, Jeff Johnston, + Stan Cox, and Frank Ch. Eigler. + * iq2000.opc: New file. Written by Ben Elliston, Frank + Ch. Eigler, Chris Moller, Jeff Johnston, and Stan Cox. + * iq2000m.cpu: New file. Written by Jeff Johnston. + * iq10.cpu: New file. Written by Jeff Johnston. + +2003-06-05 Nick Clifton <nickc@redhat.com> + + * frv.cpu (FRintieven): New operand. An even-numbered only + version of the FRinti operand. + (FRintjeven): Likewise for FRintj. + (FRintkeven): Likewise for FRintk. + (mdcutssi, media-dual-word-rotate-r-r, mqsaths, + media-quad-arith-sat-semantics, media-quad-arith-sat, + conditional-media-quad-arith-sat, mdunpackh, + media-quad-multiply-semantics, media-quad-multiply, + conditional-media-quad-multiply, media-quad-complex-i, + media-quad-multiply-acc-semantics, media-quad-multiply-acc, + conditional-media-quad-multiply-acc, munpackh, + media-quad-multiply-cross-acc-semantics, mdpackh, + media-quad-multiply-cross-acc, mbtoh-semantics, + media-quad-cross-multiply-cross-acc-semantics, + media-quad-cross-multiply-cross-acc, mbtoh, mhtob-semantics, + media-quad-cross-multiply-acc-semantics, cmbtoh, + media-quad-cross-multiply-acc, media-quad-complex, mhtob, + media-expand-halfword-to-double-semantics, mexpdhd, cmexpdhd, + cmhtob): Use new operands. + * frv.opc (CGEN_VERBOSE_ASSEMBLER_ERRORS): Define. + (parse_even_register): New function. + +2003-06-03 Nick Clifton <nickc@redhat.com> + + * frv.cpu (media-dual-word-rotate-r-r): Use a signed 6-bit + immediate value not unsigned. + +2003-06-03 Andrew Cagney <cagney@redhat.com> + + Contributed by Red Hat. + * frv.cpu: New file. Written by Dave Brolley, Catherine Moore, + and Eric Christopher. + * frv.opc: New file. Written by Catherine Moore, and Dave + Brolley. + * simplify.inc: New file. Written by Doug Evans. + +2003-05-02 Andrew Cagney <cagney@redhat.com> + + * New file. + + +Local Variables: +mode: change-log +left-margin: 8 +fill-column: 74 +version-control: never +End: diff --git a/cpu/cris.cpu b/cpu/cris.cpu new file mode 100644 index 00000000000..97b44581e78 --- /dev/null +++ b/cpu/cris.cpu @@ -0,0 +1,4553 @@ +; CRIS CPU description. -*- Scheme -*- +; +; Copyright 2003, 2004, 2007, 2009 Free Software Foundation, Inc. +; +; Contributed by Axis Communications AB. +; +; 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") + +;;;;;;;;;;;;;;;;;; -pmacro (generic ones) + +(define-pmacro (.car2 l) (.apply (.pmacro (a b) a) l)) +(define-pmacro (.cadr2 l) (.apply (.pmacro (a b) b) l)) +(define-pmacro (SI-ext x) "How to sign-extend a dword to dword (a nop)" x) +(define-pmacro (HI-ext x) "How to sign-extend a word to dword" (ext SI x)) +(define-pmacro (QI-ext x) "How to sign-extend a byte to dword" (ext SI x)) +(define-pmacro (SI-zext x) "How to zero-extend a dword to dword (a nop)" x) +(define-pmacro (HI-zext x) "How to zero-extend a word to dword" (zext SI x)) +(define-pmacro (QI-zext x) "How to zero-extend a byte to dword" (zext SI x)) +(define-pmacro + (define-pmacro-map x) + "On a list ((x0 y0) .. (xN yN)), 0 <= m <= N, (define-pmacro xm ym)" + (.splice + begin + (.unsplice + (.map + (.pmacro (l) (.apply (.pmacro (xm ym) (define-pmacro xm ym)) l)) x))) +) + +;;;;;;;;;;;;;;;;;; -arch -isa -cpu -model + +(define-arch + (name cris) + (comment "Axis Communications CRIS") + (default-alignment unaligned) + (insn-lsb0? #t) + (machs crisv0 crisv3 crisv8 crisv10 crisv32) + (isas cris) +) + +(define-isa + (name cris) + (base-insn-bitsize 16) + (liw-insns 1) + (parallel-insns 1) +) + +(define-pmacro + (define-cpu-cris x-suffix x-comment) + "Define a CRIS CPU family" + (define-cpu + (name (.sym cris x-suffix f)) + (comment x-comment) + (endian little) + ; CGEN-FIXME: Should be deduced from the default? + (word-bitsize 32) + (file-transform (.str x-suffix)) + ) +) + +; Useful when there's a need to iterate over all models. +(define-pmacro (cris-cpu-model-numbers) + "List of CRIS CPU model numbers (version register contents)" + (0 3 8 10 32) +) + +(define-pmacro (cris-cpu-models) + "List of CRIS CPU model names" + (.map (.pmacro (n) (.sym v n)) (cris-cpu-model-numbers)) +) + +; Mapping from model name to number. +(define-pmacro-map + (.map (.pmacro (n) ((.sym v n -number) n)) + (cris-cpu-model-numbers))) + +; FIXME: Rationalize these rules. +; CPU names must be distinct from the architecture name and machine names. +; The "b" suffix stands for "base" and is the convention. +; The "f" suffix stands for "family" and is the convention. +; We ignore the "b" convention, partly because v0 isn't really a "base", at +; least not for some aspects of v32. +(define-cpu-cris v0 "CRIS base family") +(define-cpu-cris v3 "CRIS v3 family") +(define-cpu-cris v8 "CRIS v8 family") +(define-cpu-cris v10 "CRIS v10 family") +(define-cpu-cris v32 "CRIS v32 family") + +(define-pmacro MACH-PRE-V32 (MACH crisv0,crisv3,crisv8,crisv10)) +(define-pmacro MACH-V3-UP (MACH crisv3,crisv8,crisv10,crisv32)) +(define-pmacro MACH-V32 (MACH crisv32)) +(define-pmacro MACH-PC MACH-PRE-V32) +(define-pmacro MACH-ACR MACH-V32) +(define-pmacro MACH-BRANCH-OFFSET-AT-INSN MACH-V32) +(define-pmacro MACH-BRANCH-OFFSET-AFTER-INSN MACH-PRE-V32) + +(define-pmacro + current-mach-is-v32 + "Whether the generated code is for V32. See comment at h-v32." + (reg h-v32) +) + +(define-pmacro (define-mach-cris x-suffix x-comment x-name) + "Define a CRIS mach" + (define-mach + (name (.sym cris x-suffix)) + ; They're all called "cris" in bfd. Watch out for breakages for some + ; uses. + (bfd-name x-name) + (comment x-comment) + (cpu (.sym cris x-suffix f))) +) + +(define-mach-cris v0 "Generic CRIS v0 CPU, ETRAX 1 .. 3" "cris") +(define-mach-cris v3 "Generic CRIS v3 CPU, ETRAX 4" "cris") +(define-mach-cris v8 "Generic CRIS v8 CPU, ETRAX 100" "cris") +(define-mach-cris v10 "Generic CRIS v10 CPU, ETRAX 100 LX" "cris") +(define-mach-cris v32 "Generic CRIS v32 CPU, ETRAX FS" "crisv32") + +(define-pmacro (define-model-simplecris x-name x-comment) + "Define a simple CRIS model" + (define-model + (name (.sym cris x-name)) + (comment x-comment) + (mach (.sym cris x-name)) + + (unit u-exec "Execution Unit" () 1 1 () () () ()) + (unit u-mem "Memory Unit" () 1 1 () () () ()) + + (unit u-const16 "Fetch 16-bit operand" () 1 1 () () () ()) + (unit u-const32 "Fetch 32-bit operand" () 1 1 + () () () ()) + ; Used in special-case insn, for example arithmetic with PC destination. + (unit u-stall "Stall unit" () 1 1 () () () ()) + (unit u-skip4 "Skip 4 bytes" () 1 1 () () () ()) + (unit u-multiply "Multiply Unit" () 1 1 ((MACH crisv10)) () () ()) + (unit u-movem "Movem Unit" () 1 1 () + ((Rd INT -1)) + () ())) +) + +(define-model-simplecris v0 "Model of CRIS v0, ETRAX 1 .. 3") +(define-model-simplecris v3 "Model of CRIS v3, ETRAX 4") +(define-model-simplecris v8 "Model of CRIS v8, ETRAX 100") +(define-model-simplecris v10 "Model of CRIS v10, ETRAX 100 LX") + +; For some reason, we get an error: +; Generating arch.h ... +; ERROR: In procedure vector-ref: +; ERROR: Wrong type argument in position 1: () +; if we include timings for machs that we don't generate sims for. +; Last checked: CVS as of 2004-11-18. +; CGEN-FIXME: Looks like another CGEN bug. When it's fixed (or when +; generating sims for v0, v3 or v8), add 0, 3 and 8 to +; simplecris-timing-models. But before that, simplecris-timing-x has to +; be rewritten to work on a multiple-element-list, not assume a single +; element. (A change which seems likely to depend on lexical scoping for +; macros to be introduced: try the obvious implementation.) +(define-pmacro simplecris-timing-models (10)) +(define-pmacro (simplecris-common-timing x-units) + "Make timing models, using x-units for all simplecris-timing-models" + ; CGEN-FIXME: Another CGEN bug: the part (.unsplice (10)) will remain + ; unexpanded in (.sym crisv (.unsplice (10)) if we write this as + ; ((.splice (.sym crisv (.unsplice simplecris-timing-models)) + ; (.unsplice x-units))) + ((.splice (.sym crisv (.apply (.pmacro (x) x) simplecris-timing-models)) + (.unsplice x-units))) +) + +(define-pmacro-map + ( + ; Timing for memory instructions running on a simple cris model. + ((simplecris-mem-timing) (simplecris-common-timing + ((unit u-mem) (unit u-exec)))) + ; Timing for movem instructions running on a simple cris model. + ((simplecris-movem-timing) (simplecris-common-timing + ((unit u-movem) (unit u-exec)))) + ; Similar, for an 8- or 16-bit constant ([PC+]) operand. + ((simplecris-const-timing-HI) + (simplecris-common-timing + ((unit u-const16) (unit u-exec)))) + ; Similar, for a 32-bit constant ([PC+]) operand. + ((simplecris-const-timing-SI) + (simplecris-common-timing + ((unit u-const32) (unit u-exec)))) + ; Similar, no particular operand. + ((simplecris-timing) (simplecris-common-timing + ((unit u-exec))))) +) + +(define-model + (name crisv32) + (comment "Model of CRISv32") + (mach crisv32) + + (state + ; Bitmask of h-gr register (0..15) and h-sr register (17..31) + ; modified by 3rd previous insn, updated by the u-exec unit. + ; Because there's no need to mark writes to special registers BZ and + ; WZ, bit 16 is for jump mark and bit 20 for memory-write mark. + (prev-prev-prev-modf-regs UINT) + + ; Ditto for the 2nd previous insn. + (prev-prev-modf-regs UINT) + + ; Ditto for the previous insn. + (prev-modf-regs UINT) + + ; Bit-mask for regs modified by the current insn, propagated to + ; prev-modf-regs. + (modf-regs UINT) + + ; Registers loaded by movem are not forwarded to the execution + ; stage, so we need to insert stall-cycles for ordinary insns + ; accessing such registers. In addition to the *modf-regs + ; above, these are set to tell *ordinary* insns which registers + ; are inaccessible. + + (prev-prev-prev-movem-dest-regs UINT) + + ; Ditto for the 2nd previous insn. + (prev-prev-movem-dest-regs UINT) + + ; Ditto for the previous insn. + (prev-movem-dest-regs UINT) + + ; Bit-mask for regs modified by the current insn, propagated to + ; prev-movem-dest-regs. + (movem-dest-regs UINT)) + + ; It seems this pipeline description isn't used at all; this is just + ; for show. + ; Noteworthy is the placement of the memory stage before the execute stage. + (pipeline all "" () ((fetch) (decode) (memory) (execute) (writeback))) + + ; Units that contribute only a constant pipeline delay are not included. + (unit u-mem "Memory Unit" () 1 1 () + ((Rs INT -1)) + () ()) + + ; Artificial units for read/write-related hazard accounting. + (unit u-mem-r "Memory Unit Read" () 1 1 () () () ()) + (unit u-mem-w "Memory Unit Write" () 1 1 () () () ()) + + (unit u-movem-rtom "Movem-to-memory Unit" () 1 1 () + ((Rs INT -1) (Rd INT -1)) + () ()) + (unit u-movem-mtor "Movem-to-register Unit" () 1 1 () + ((Rs INT -1) (Rd INT -1)) + () ()) + (unit u-multiply "Multiply Unit" () 1 1 () + ((Rs INT -1) (Rd INT -1)) + () ()) + (unit u-branch "Branch Unit" () 1 1 () + () + () ()) + (unit u-jump-r "Jump-to-register Unit" () 1 1 () + ((Rs INT -1)) + () ()) + (unit u-jump-sr "Jump-to-special-register Unit" () 1 1 () + ((Ps INT -1)) + () ()) + (unit u-jump "JAS/BAS Unit, saving PC" () 1 1 () + () + ((Pd INT -1)) ()) + + ; To keep track of PC; not really functional units. + (unit u-const16 "Fetch 16-bit operand" () 1 1 () () () ()) + (unit u-const32 "Fetch 32-bit operand" () 1 1 () () () ()) + (unit u-skip4 "Skip 4 bytes" () 1 1 () () () ()) + + ; For v32, we need to keep track of inputs (for movem destination + ; cycle penalties) and output (for e.g. memory source and jump + ; source cycle penalties). + (unit u-exec "Execution Unit" () 1 1 () + ((Rd INT -1) (Rs INT -1)) + ((Rd INT -1)) + ()) + + ; Special case of u-exec for movem: don't treat Rd as an incoming + ; parameter. + (unit u-exec-movem "Execution Unit" () 1 1 () + ((Rs INT -1)) + ((Rd INT -1)) + ()) + + ; Special case of u-exec when the destination is a special + ; register. + (unit u-exec-to-sr "Execution Unit" () 1 1 () + ((Rs INT -1)) + ((Pd INT -1)) ()) +) + +(define-pmacro (crisv32-timing-destreg d) + "Timing for instructions running on a crisv32 model" + ((crisv32 + (.splice unit u-exec (.unsplice d)))) +) +(define-pmacro (crisv32-timing) (crisv32-timing-destreg ())) + +(define-pmacro (cris-timing-Rd-sfield) + (crisv32-timing-destreg ((out Rd Rd-sfield))) +) + +(define-pmacro (crisv32-timing-c-HI) + ((crisv32 (unit u-const16) (unit u-exec))) +) + +(define-pmacro-map + ((crisv32-timing-c-QI crisv32-timing-c-HI) + ((crisv32-timing-c-SI) ((crisv32 (unit u-const32) (unit u-exec)))) + ((crisv32-timing-c-sr-SI) ((crisv32 (unit u-const32) (unit u-exec-to-sr)))) + ((crisv32-reg-sr-timing) ((crisv32 (unit u-exec-to-sr)))) + ((crisv32-mem-sr-timing) + ((crisv32 (unit u-mem) (unit u-mem-r) (unit u-exec-to-sr)))) + ((crisv32-mem-timing) ((crisv32 (unit u-mem) (unit u-mem-r) (unit u-exec)))) + ((crisv32-mem-write-timing) ((crisv32 (unit u-mem) (unit u-exec) (unit u-mem-w))))) +) + +(define-pmacro-map + ( + ; Timing for instructions using memory operands. + ((cris-mem-timing) (.splice (.unsplice (simplecris-mem-timing)) + (.unsplice (crisv32-mem-timing)))) + ; Timing for instructions using memory operands. + ((cris-mem-write-timing) (.splice + (.unsplice (simplecris-mem-timing)) + (.unsplice (crisv32-mem-write-timing)))) + ; Timing for moves from general register to special register. + ((cris-reg-sr-timing) (.splice (.unsplice (simplecris-timing)) + (.unsplice (crisv32-reg-sr-timing)))) + ; Timing for moves from memory to special register. + ((cris-mem-sr-timing) (.splice (.unsplice (simplecris-mem-timing)) + (.unsplice (crisv32-mem-sr-timing)))) + ; Timing for non-mul, non-memory, non-special-register, 16-bit instructions. + ((cris-timing) (.splice (.unsplice (simplecris-timing)) + (.unsplice (crisv32-timing)))) + ; Timing for instructions with 8- or 16-bit constant operand ([PC+]). + ((cris-timing-const-HI) (.splice + (.unsplice (simplecris-const-timing-HI)) + (.unsplice (crisv32-timing-c-HI)))) + ; Timing for instructions with a 32-bit constant operand ([PC+]). + ((cris-timing-const-SI) (.splice + (.unsplice (simplecris-const-timing-SI)) + (.unsplice (crisv32-timing-c-SI)))) + ; Like cris-timing-const-SI, but destination special register. + ((cris-timing-const-sr-SI) (.splice + (.unsplice (simplecris-const-timing-SI)) + (.unsplice (crisv32-timing-c-sr-SI)))) + ; Like cris-timing-const-HI, but destination special register. + ((cris-timing-const-sr-HI) (.splice + (.unsplice (simplecris-const-timing-HI)) + (.unsplice (crisv32-timing-c-sr-SI))))) +) + +(define-pmacro cris-timing-const-QI cris-timing-const-HI) +(define-pmacro cris-timing-const-sr-QI cris-timing-const-sr-HI) + +(define-pmacro (simplecris-common-writable-specregs) + "The common writable special registers in pre-v32 models." + ((HI 5) (SI 9) (SI 10) (SI 11) (SI 12) (SI 13)) +) + +(define-pmacro (simplecris-common-readable-specregs) + "The common readable special registers in pre-v32 models." + (.splice (.unsplice (simplecris-common-writable-specregs)) + (QI 0) (QI 1) (HI 4) (SI 8)) +) + +(define-pmacro (cris-implemented-writable-specregs-v0) + "Special writable registers in v0 and their sizes" + (.splice (.unsplice (simplecris-common-writable-specregs)) (HI 6) (HI 7)) +) +(define-pmacro + cris-implemented-specregs-const-v0 + cris-implemented-writable-specregs-v0 +) +(define-pmacro (cris-implemented-readable-specregs-v0) + "Special readable registers in v0 and their sizes" + (.splice (.unsplice (simplecris-common-readable-specregs)) (HI 6) (HI 7)) +) + +(define-pmacro (cris-implemented-writable-specregs-v3) + "Special writable registers in v3 and their sizes" + (.splice (.unsplice (cris-implemented-writable-specregs-v0)) (SI 14)) +) +(define-pmacro + cris-implemented-specregs-const-v3 + cris-implemented-writable-specregs-v3 +) +(define-pmacro (cris-implemented-readable-specregs-v3) + "Special readable registers in v3 and their sizes" + (.splice (.unsplice (cris-implemented-readable-specregs-v0)) (SI 14)) +) + +(define-pmacro (cris-implemented-writable-specregs-v8) + "Special writable registers in v8 and their sizes" + (.splice (.unsplice (simplecris-common-writable-specregs)) (SI 14)) +) +(define-pmacro + cris-implemented-specregs-const-v8 + cris-implemented-writable-specregs-v8 +) +(define-pmacro (cris-implemented-readable-specregs-v8) + "Special readable registers in v8 and their sizes" + (.splice (.unsplice (simplecris-common-readable-specregs)) (SI 14)) +) + +(define-pmacro (cris-implemented-writable-specregs-v10) + "Special writable registers in v10 and their sizes" + (.splice (.unsplice (simplecris-common-writable-specregs)) + (SI 7) (SI 14) (SI 15)) +) +(define-pmacro + cris-implemented-specregs-const-v10 + cris-implemented-writable-specregs-v10 +) +(define-pmacro (cris-implemented-readable-specregs-v10) + "Special registers in v10 and their sizes" + (.splice (.unsplice (simplecris-common-readable-specregs)) + (SI 7) (SI 14) (SI 15)) +) + +(define-pmacro (cris-implemented-writable-specregs-v32) + "Special writable registers in v32 and their sizes" + ((SI 2) (QI 3) + (SI 5) (SI 6) (SI 7) (SI 9) + (SI 10) (SI 11) (SI 12) (SI 13) (SI 14) (SI 15)) +) +(define-pmacro (cris-implemented-readable-specregs-v32) + "Special readable registers in v32 and their sizes" + (.splice (.unsplice (cris-implemented-writable-specregs-v32)) + (QI 0) (QI 1) (HI 4) (SI 8)) +) + +; For v32, all special register operations on constants (that is, +; move) take 32-bit operands, not the real size of the register, as in +; other move operations. +(define-pmacro (cris-implemented-specregs-const-v32) + (.map (.pmacro (x) (SI (.cadr2 x))) + (cris-implemented-writable-specregs-v32)) +) + +(define-pmacro cris-swap-codes + "CRIS Swap codes in numeric order (no zero)" + ( r b br w wr wb wbr + n nr nb nbr nw nwr nwb nwbr) +) + +(define-pmacro cris-flagnames + "CRIS flag field values, dest and src fields concatenated" + (c v z n x i u p) ; ... b m for pre-v32 +) + +(define-pmacro-map + ; Bitnumber for each respective flag. + (.map (.pmacro (x num) ((.sym x -bitnumber) num)) + cris-flagnames (.iota 8)) +) + +; I give up. Here's a perl-script to get the values I want for this macro +; (not working along list principles, though). You can run this region. +; perl -e '$x = "cvznxiup"; for ($i = 0; $i < 256; $i++) { $s = ""; +; for ($j = 0; $j < 8; $j++) { if ($i & (1 << $j)) { +; $s .= substr ($x, $j, 1);}} +; printf ("%s%s", $s eq "" ? "_" : $s, (($i + 1) % 8) == 0 ? "\n " : " "); }' +(define-pmacro cris-flag-combinations + "Combinations of flags in numeric order" + (_ c v cv z cz vz cvz + n cn vn cvn zn czn vzn cvzn + x cx vx cvx zx czx vzx cvzx + nx cnx vnx cvnx znx cznx vznx cvznx + i ci vi cvi zi czi vzi cvzi + ni cni vni cvni zni czni vzni cvzni + xi cxi vxi cvxi zxi czxi vzxi cvzxi + nxi cnxi vnxi cvnxi znxi cznxi vznxi cvznxi + u cu vu cvu zu czu vzu cvzu + nu cnu vnu cvnu znu cznu vznu cvznu + xu cxu vxu cvxu zxu czxu vzxu cvzxu + nxu cnxu vnxu cvnxu znxu cznxu vznxu cvznxu + iu ciu viu cviu ziu cziu vziu cvziu + niu cniu vniu cvniu zniu czniu vzniu cvzniu + xiu cxiu vxiu cvxiu zxiu czxiu vzxiu cvzxiu + nxiu cnxiu vnxiu cvnxiu znxiu cznxiu vznxiu cvznxiu + p cp vp cvp zp czp vzp cvzp + np cnp vnp cvnp znp cznp vznp cvznp + xp cxp vxp cvxp zxp czxp vzxp cvzxp + nxp cnxp vnxp cvnxp znxp cznxp vznxp cvznxp + ip cip vip cvip zip czip vzip cvzip + nip cnip vnip cvnip znip cznip vznip cvznip + xip cxip vxip cvxip zxip czxip vzxip cvzxip + nxip cnxip vnxip cvnxip znxip cznxip vznxip cvznxip + up cup vup cvup zup czup vzup cvzup + nup cnup vnup cvnup znup cznup vznup cvznup + xup cxup vxup cvxup zxup czxup vzxup cvzxup + nxup cnxup vnxup cvnxup znxup cznxup vznxup cvznxup + iup ciup viup cviup ziup cziup vziup cvziup + niup cniup vniup cvniup zniup czniup vzniup cvzniup + xiup cxiup vxiup cvxiup zxiup czxiup vzxiup cvzxiup + nxiup cnxiup vnxiup cvnxiup znxiup cznxiup vznxiup cvznxiup + ) +) + +(define-pmacro cc-condition (not cbit)) +(define-pmacro cs-condition cbit) +(define-pmacro ne-condition (not zbit)) +(define-pmacro eq-condition zbit) +(define-pmacro vc-condition (not vbit)) +(define-pmacro vs-condition vbit) +(define-pmacro pl-condition (not nbit)) +(define-pmacro mi-condition nbit) +(define-pmacro ls-condition (or cbit zbit)) +(define-pmacro hi-condition (not (or cbit zbit))) +(define-pmacro ge-condition (not (xor vbit nbit))) +(define-pmacro lt-condition (xor vbit nbit)) +(define-pmacro gt-condition (not (or (xor vbit nbit) zbit))) +(define-pmacro le-condition (or (xor vbit nbit) zbit)) +(define-pmacro a-condition 1) + +; FIXME: define this properly for v10 and pre-v10. +(define-pmacro wf-condition pbit) + +(define-pmacro (cris-condition condno) + "Return condition state for condition number CONDNO" + (sequence + BI + ((SI tmpcond) (BI condres)) + (set tmpcond condno) + (.splice + cond + (.unsplice + (.map + (.pmacro + (condn condc) + ((eq tmpcond condn) (set condres (.sym condc -condition)))) + (.iota 16) + cris-condition-codes))) + condres) +) + +;;;;;;;;;;;;;;;;;; -keyword + +; General registers. +(define-pmacro (cris-general-gregs) + (.splice (SP 14) (.unsplice (.map (.pmacro (n) ((.sym R n) n)) (.iota 15)))) +) + +; Can't keep more than one gr-names definition at the same time; +; generated enum declarations in sim/cris/cris-desc.h will collide. +; FIXME: (include "different-mach-parts") + +(define-keyword + (name gr-names-pcreg) + (attrs MACH-PC) + (print-name h-gr-real-pc) + ; Put PC first so it is preferred over r15. + (.splice values (PC 15) (.unsplice (cris-general-gregs))) +) + +(define-keyword + (name gr-names-acr) + (attrs MACH-ACR) + ; The print-name directive will control the enum prefix. With the + ; arguably more appropriate h-gr-v32 or h-gr-acr, we'd get names like + ; H_GR_ACR_R0 instead of H_GR_R0. Since we have to choose something for + ; unprefixed names, we use the CRISv32 names. FIXME: All users should + ; change to use H_GR_V32_R0 (etc.), then change this to h-gr-v32. + (print-name h-gr) + ; Put ACR first so it is preferred over r15. + (.splice values (ACR 15) (.unsplice (cris-general-gregs))) +) + +(define-keyword + (name gr-names-v32) + (attrs MACH-V32) + ; In preparation for implementing the FIXME above. + (print-name h-gr-v32) + ; Put ACR first so it is preferred over r15. + (.splice values (ACR 15) (.unsplice (cris-general-gregs))) +) + +; Special registers with names common to all. +(define-pmacro (cris-general-pregs) + (.splice + (VR 1) + (SRP 11) + (.unsplice (.map (.pmacro (n) ((.sym P n) n)) (.iota 15)))) +) + +(define-keyword + (name p-names-v10) + (attrs MACH-PRE-V32) + (print-name h-sr-pre-v32) + (.splice + values + (CCR 5) + (MOF 7) + (IBR 9) + (IRP 10) + (BAR 12) + (DCCR 13) + (BRP 14) + (USP 15) + (.unsplice (cris-general-pregs))) +) + +(define-keyword + (name p-names-v32) + (attrs MACH-V32) + ; See comment for gr-names-acr. + (print-name h-sr) + (.splice + values + (BZ 0) + (PID 2) + (SRS 3) + (WZ 4) + (EXS 5) + (EDA 6) + (MOF 7) + (DZ 8) + (EBP 9) + (ERP 10) + (NRP 12) + (CCS 13) + (USP 14) + (SPC 15) + (.unsplice (cris-general-pregs))) +) + +; Similarly as for h-gr-v32, in preparation. +(define-keyword + (name p-names-v32-x) + (attrs MACH-V32) + ; See comment for gr-names-acr. + (print-name h-sr-v32) + (.splice + values + (BZ 0) + (PID 2) + (SRS 3) + (WZ 4) + (EXS 5) + (EDA 6) + (MOF 7) + (DZ 8) + (EBP 9) + (ERP 10) + (NRP 12) + (CCS 13) + (USP 14) + (SPC 15) + (.unsplice (cris-general-pregs))) +) + +(define-pmacro p0 (reg h-sr 0)) +(define-pmacro vr (reg h-sr 1)) +(define-pmacro pid (reg h-sr 2)) +(define-pmacro srs (reg h-sr 3)) +(define-pmacro p4 (reg h-sr 4)) +(define-pmacro ccr (reg h-sr 5)) +(define-pmacro mof (reg h-sr 7)) +(define-pmacro p8 (reg h-sr 8)) +(define-pmacro ibr (reg h-sr 9)) +(define-pmacro ebp (reg h-sr 9)) +(define-pmacro erp (reg h-sr 10)) +(define-pmacro srp (reg h-sr 11)) +(define-pmacro ccs (reg h-sr 13)) +(define-pmacro dccr (reg h-sr 13)) +(define-pmacro usp (reg h-sr 14)) +(define-pmacro spc (reg h-sr 15)) + +(define-pmacro sp (reg h-gr 14)) +(define-pmacro acr (reg h-gr 15)) + +(define-pmacro cris-condition-codes + "CRIS condition codes in numeric order" + (cc cs ne eq vc vs pl mi ls hi ge lt gt le a wf) +) + +; No use having different lists; this is the only CC that +; differs between v10 and v32, and mostly in the name. +(define-pmacro sb wf) + + +;;;;;;;;;;;;;;;;;; -hardware + +;; Various constant generators. + +(define-hardware + (name h-inc) + (comment "autoincrement-bit syntax specifier") + (type immediate (UINT 1)) + (values keyword "" (("" 0) ("+" 1))) +) + +(define-hardware + (name h-ccode) + (comment "Condition code specifier") + (type immediate (UINT 4)) + (values keyword "" + (.map (.pmacro (x y) ((.str x) y)) + cris-condition-codes (.iota 16))) +) + +(define-hardware + (name h-swap) + (comment "Swap option specifier") + (type immediate (UINT 4)) + (values + keyword "" + (.splice + (" " 0) + (.unsplice + (.map + (.pmacro (x y) ((.str x) y)) cris-swap-codes (.iota 15 1))))) +) + +(define-hardware + (name h-flagbits) + (comment "Flag bits specifier") + (type immediate (UINT 8)) + (values + keyword "" + (.map (.pmacro (x y) ((.str x) y)) cris-flag-combinations (.iota 256))) +) + +; Apparently, the semantic-name isn't used for accessors, so external +; users like the sim glue and SID sees the -v32 and -pre-v32 munged names. +; Defining "dispatchers"; virtual registers whose getter and setter works +; on the "real" mach variants, seems to help. CGEN-FIXME: Make +; semantic-name set the generated names. +(define-pmacro (cris-d-hwreg x-name x-type) + (define-hardware + (name x-name) + (comment (.str "Dispatcher for " x-name)) + (attrs VIRTUAL) + (type register x-type) + (get () (reg (.sym x-name -x))) + (set (val) (set (reg (.sym x-name -x)) val))) +) +(define-pmacro (cris-d-hwregf-a x-name x-type x-n x-attrs) + (define-hardware + (name x-name) + (comment (.str "Dispatcher for " x-name)) + (.splice attrs VIRTUAL (.unsplice x-attrs)) + (type register x-type (x-n)) + (get (index) (reg (.sym x-name -x) index)) + (set (index val) (set-quiet (reg (.sym x-name -x) index) val))) +) +(define-pmacro (cris-d-hwregf x-name x-type x-n) + (cris-d-hwregf-a x-name x-type x-n ()) +) +(define-pmacro (cris-d-hwregf-p x-name x-type x-n) + (cris-d-hwregf-a x-name x-type x-n (PROFILE)) +) + +; At first glance we could use (eq-attr (current-mach) ...) for +; everything, but that seems sometimes (always?) to yield false. For +; ifields, it causes noncompilable C-code. For the insn semantics code, +; it causes tests movei.ms and mulv32.ms to fail, apparently because the +; current-mach-is-v32 usage in flags setting is miscompiled as 0 (or +; rather, misgenerated). Instead we use different definitions of a +; MACH-tagged virtual register yielding a constant, together with a +; pmacro. CGEN-FIXME: If eq-attr is someday fixed, we could just remove +; these h-v32 virtual register definitions and change the pmacro +; definition for current-mach-is-v32. +(define-hardware + (semantic-name h-v32) + (name h-v32-v32) + (attrs MACH-V32 VIRTUAL) + (type register BI) + (get () (const BI 1)) + (set (val) (error "Can't set h-v32")) +) +(define-hardware + (semantic-name h-v32) + (name h-v32-non-v32) + (attrs MACH-PRE-V32 VIRTUAL) + (type register BI) + (get () (const BI 0)) + (set (val) (error "Can't set h-v32")) +) + +;; "Real" hardware. + +(define-hardware + (name h-pc) + (comment "program counter") + (attrs PC PROFILE) + (type pc) + ; There's no bit 0 in PC, so just ignore it when jumping etc. + (set (val) (set (raw-reg h-pc) (and val (inv 1)))) +) + +; Note that setting register 15 isn't handled here, but in each insn, so +; the proper "jump" attributes and other special stuff for speedy +; execution can be present. +(cris-d-hwregf-p h-gr SI 16) +(define-hardware + (semantic-name h-gr-x) + (name h-gr-pc) + (attrs MACH-PC VIRTUAL) + (comment "General purpose registers, aborting on PC access") + (type register SI (16)) + (indices extern-keyword gr-names-pcreg) + (get + (index) + (if SI (eq index 15) + (error SI "General register read of PC is not implemented.") + (reg SI h-gr-real-pc index))) + (set + (index val) + (sequence + () + (if (eq index 15) + (error "General register write to PC is not implemented.")) + (set (reg SI h-gr-real-pc index) val))) +) +(define-hardware + (name h-gr-real-pc) + (attrs MACH-PC) + (comment "General purpose registers") + (type register SI (16)) + (indices extern-keyword gr-names-pcreg) +) + +; We have to use a virtual register trick to get the "raw", unaccounted +; contents of the global register; the raw-reg RTX only works for +; non-virtual register files. +(define-hardware + (semantic-name h-raw-gr) + (name h-raw-gr-pc) + (attrs MACH-PC VIRTUAL) + (comment "Unaccounted version of general purpose registers") + (type register SI (16)) + (get (index) (raw-reg h-gr-real-pc index)) + (set (index val) (set-quiet (raw-reg h-gr-real-pc index) val)) +) +(define-hardware + (semantic-name h-gr-x) + (name h-gr-acr) + (attrs MACH-ACR) + (comment "General purpose registers") + (type register SI (16)) + (indices extern-keyword gr-names-acr) +) +(define-hardware + (semantic-name h-raw-gr) + (name h-raw-gr-acr) + (attrs MACH-ACR VIRTUAL) + (comment "Unaccounted version of general purpose registers") + (type register SI (16)) + (get (index) (raw-reg h-gr-x index)) + (set (index val) (set-quiet (raw-reg h-gr-x index) val)) +) + +; FIXME: get and set semantics? Unknown how to split semantics best; with +; get/set semantics or within the insn specification. Doing the former for +; now. Should use different names for pre-v10. +; FIXME: No dccr for v0 and v3. Different high flag bits. +(cris-d-hwregf-p h-sr SI 16) +(define-pmacro + (cris-h-sr machver) + (define-hardware + (semantic-name h-sr-x) + (name (.sym h-sr-v machver)) + (attrs (MACH (.sym crisv machver))) + (comment (.str "Special registers for v" machver)) + (type register SI (16)) + (indices extern-keyword p-names-v10) + (get + (index) + (cond + SI + ((orif (orif (eq index (regno p0)) (eq index (regno p4))) + (eq index (regno p8))) 0) + ((eq index (regno vr)) machver) + ((orif (eq index (regno ccr)) + (eq index (regno dccr))) + ; Return "P U I X N Z V C" for the low 8 bits. + ; FIXME: More bits. + (or SI + (and SI (raw-reg SI h-sr-x (regno ccr)) #xffffff00) + (or + (zext SI (reg BI h-cbit)) + (or + (sll (zext SI (reg BI h-vbit)) 1) + (or + (sll (zext SI (reg BI h-zbit)) 2) + (or + (sll (zext SI (reg BI h-nbit)) 3) + (or + (sll (zext SI (reg BI h-xbit)) 4) + (or + (sll (zext SI (reg BI h-ibit)) 5) + (or + (sll (zext SI (reg BI h-ubit)) 6) + (or + (sll (zext SI (reg BI h-pbit)) 7) + 0)))))))))) + (else (raw-reg SI h-sr-x index)))) + (set + (index val) + (cond + ((orif (orif (eq index (regno p0)) (eq index (regno p4))) + (orif (eq index (regno p8)) (eq index (regno vr)))) + (nop)) + ((orif (eq index (regno ccr)) (eq index (regno dccr))) + (sequence + () + (set (reg BI h-cbit) (if BI (ne SI (and val (sll 1 0)) 0) 1 0)) + (set (reg BI h-vbit) (if BI (ne SI (and val (sll 1 1)) 0) 1 0)) + (set (reg BI h-zbit) (if BI (ne SI (and val (sll 1 2)) 0) 1 0)) + (set (reg BI h-nbit) (if BI (ne SI (and val (sll 1 3)) 0) 1 0)) + (set (reg BI h-xbit) (if BI (ne SI (and val (sll 1 4)) 0) 1 0)) + (set (reg BI h-ibit) (if BI (ne SI (and val (sll 1 5)) 0) 1 0)) + (set (reg BI h-ubit) (if BI (ne SI (and val (sll 1 6)) 0) 1 0)) + (set (reg BI h-pbit) (if BI (ne SI (and val (sll 1 7)) 0) 1 0)) + (set-quiet (raw-reg SI h-sr-x (regno ccr)) val) + (set-quiet (raw-reg SI h-sr-x (regno dccr)) val))) + (else (set-quiet (raw-reg SI h-sr-x index) val))))) +) + +(cris-h-sr 0) +(cris-h-sr 3) +(cris-h-sr 8) +(cris-h-sr 10) + +(define-hardware + (semantic-name h-sr-x) + (name h-sr-v32) + (attrs MACH-V32) + (comment "Special registers for v32") + (type register SI (16)) + (indices extern-keyword p-names-v32) + + (get + (index) + (cond + SI + ((orif (orif (eq index (regno p0)) (eq index (regno p4))) + (eq index (regno p8))) 0) + ((eq index (regno vr)) 32) + ((eq index (regno ccs)) + ; Return "S R P U I X N Z V C" for the low 10 bits. + (or SI + (and SI (raw-reg SI h-sr-x (regno ccs)) #x3ffffc00) + (or + (zext SI (reg BI h-cbit)) + (or + (sll (zext SI (reg BI h-vbit)) 1) + (or + (sll (zext SI (reg BI h-zbit)) 2) + (or + (sll (zext SI (reg BI h-nbit)) 3) + (or + (sll (zext SI (reg BI h-xbit)) 4) + (or + (sll (zext SI (reg BI h-ibit)) 5) + (or + (sll (zext SI (reg BI h-ubit)) 6) + (or + (sll (zext SI (reg BI h-pbit)) 7) + (or + (sll (zext SI (reg BI h-rbit)) 8) + (or + (sll (zext SI (reg BI h-sbit)) 9) + (or + (sll (zext SI (reg BI h-mbit)) 30) + (or + (sll (zext SI (reg BI h-qbit)) 31) + 0)))))))))))))) + ((eq index (regno usp)) + ; In user mode, return general stack pointer. + (if BI (reg BI h-ubit) + (raw-reg SI h-gr-x (regno sp)) + (raw-reg SI h-sr-x (regno usp)))) + (else (raw-reg SI h-sr-x index)))) + + (set + (index val) + (cond + ((orif (orif (eq index (regno p0)) (eq index (regno p4))) + (orif (eq index (regno p8)) (eq index (regno vr)))) + (nop)) + ((eq index (regno ccs)) + (sequence + () + ; Protected bits are handled as such in the respective setter function. + (set (reg BI h-cbit) (if BI (ne SI (and val (sll 1 0)) 0) 1 0)) + (set (reg BI h-vbit) (if BI (ne SI (and val (sll 1 1)) 0) 1 0)) + (set (reg BI h-zbit) (if BI (ne SI (and val (sll 1 2)) 0) 1 0)) + (set (reg BI h-nbit) (if BI (ne SI (and val (sll 1 3)) 0) 1 0)) + (set (reg BI h-xbit) (if BI (ne SI (and val (sll 1 4)) 0) 1 0)) + (set (reg BI h-ibit) (if BI (ne SI (and val (sll 1 5)) 0) 1 0)) + (set (reg BI h-sbit) (if BI (ne SI (and val (sll 1 9)) 0) 1 0)) + (set (reg BI h-mbit) (if BI (ne SI (and val (sll 1 30)) 0) 1 0)) + (set (reg BI h-pbit) (if BI (ne SI (and val (sll 1 7)) 0) 1 0)) + (set (reg BI h-rbit) (if BI (ne SI (and val (sll 1 8)) 0) 1 0)) + (set (reg BI h-qbit) (if BI (ne SI (and val (sll 1 31)) 0) 1 0)) + ; Set the U bit last, so the setter functions for the other bits + ; don't see it as set from this operation. It is not cleared from + ; this operation, so we don't have to handle that; it's only + ; cleared "manually" from within simulator-specific context-switch + ; machinery. + (set (reg BI h-ubit) (if BI (ne SI (and val (sll 1 6)) 0) 1 0)) + (set-quiet (raw-reg SI h-sr-x index) val))) + ((eq index (regno usp)) + ; In user mode, set general register 14 too, whenever setting USP. + (sequence + () + (if (reg BI h-ubit) (set (raw-reg SI h-gr-x (regno sp)) val)) + (set (raw-reg SI h-sr-x (regno usp)) val))) + ((eq index (regno srs)) + (if (not (reg BI h-ubit)) (set (raw-reg h-sr-x (regno srs)) val))) + ((eq index (regno ebp)) + (if (not (reg BI h-ubit)) (set (raw-reg h-sr-x (regno ebp)) val))) + ((eq index (regno pid)) + (if (not (reg BI h-ubit)) + (sequence + () + (c-call VOID "@cpu@_write_pid_handler" val) + (set (raw-reg h-sr-x (regno pid)) val)))) + ((eq index (regno spc)) + (if (not (reg BI h-ubit)) (set (raw-reg h-sr-x (regno spc)) val))) + (else (set-quiet (raw-reg SI h-sr-x index) val)))) +) + +(define-hardware + (name h-supr) + (attrs MACH-V32 VIRTUAL) + (comment "Support registers") + (type register SI (16)) + (values keyword "" (.map (.pmacro (y) ((.str S y) y)) (.iota 16))) + (get (index) (c-call SI "@cpu@_read_supr" index)) + (set (index val) (c-call VOID "@cpu@_write_supr" index val)) +) + +(define-pmacro (cris-dsh semantic-name name comment attrs type) + "Like dsh, but the semantic-name is separate" + (define-full-hardware + name comment attrs semantic-name type () () () () () ()) +) + +; We define the condition codes that hold arithmetic flags separately +; and "or" them in, in the get and set methods of the special +; registers. We define arithmetic flags as any of C V Z N X. They +; thankfully have that order (zero-based) in all processor versions. + +; To avoid having two variants of most move-type instructions because V32 +; doesn't set C and V (and N and Z), we fake the setting to virtual +; registers which have two different implementations. +(define-pmacro (cris-move-flag f f-name f-whence) + "Flag set differently in pre-v32 and v32 in some cases" + (begin + (dsh (.sym h- f bit) (.str f-name " bit") () (register BI)) + (cris-d-hwreg (.sym h- f bit-move) BI) + (define-hardware + (semantic-name (.sym h- f bit-move-x)) + (name (.sym h- f bit-move-v32)) + (comment (.str f-name " bit set in " f-whence " instructions, ignored")) + (attrs MACH-V32 VIRTUAL) + (type register BI) + (get + () + (sequence BI () + (error (.str "Can't get h-" f "bit-move on CRISv32")) 0)) + (set (val) (nop))) + (define-hardware + (semantic-name (.sym h- f bit-move-x)) + (name (.sym h- f bit-move-pre-v32)) + (comment + (.str + f-name " bit set in " f-whence " instructions, same as " f "bit")) + (attrs MACH-PRE-V32 VIRTUAL) + (type register BI) + (get () (reg (.sym h- f bit))) + (set (val) (set (reg (.sym h- f bit)) val)))) +) + +(cris-move-flag c "carry" "move-type") +(cris-move-flag v "overflow" "move-type") +(cris-move-flag z "zero" "moveq") +(cris-move-flag n "sign" "moveq") + +(dsh h-xbit "extended-arithmetic bit" () (register BI)) +(cris-d-hwreg h-ibit BI) +(cris-dsh h-ibit-x h-ibit-pre-v32 + "interrupt-enable bit" (MACH-PRE-V32) (register BI)) +(dsh h-pbit "sequence-broken bit" ((MACH crisv10,crisv32)) (register BI)) +(dsh h-rbit "carry bit for MCP+restore-p bit" (MACH-V32) (register BI)) +(cris-d-hwreg h-ubit BI) +(cris-dsh h-ubit-x h-ubit-pre-v32 + "user mode bit" ((MACH crisv10)) (register BI)) +(dsh h-gbit "guru mode bit" (MACH-V32) (register BI)) + +; When doing a transition from kernel to user mode on V32, we save the +; stack pointer in an internal register and copy USP to R14, so we don't +; need non-trivial handlers for general registers. +(dsh + h-kernel-sp + "Kernel stack pointer during user mode" + (MACH-V32) + (register SI) +) + +(define-hardware + (semantic-name h-ubit-x) + (name h-ubit-v32) + (comment "User mode bit") + (attrs MACH-V32) + (type register BI) + (set + (val) + (sequence + () + (if (andif val (not (raw-reg BI h-ubit-x))) + (sequence + () + (set (reg SI h-kernel-sp) (raw-reg h-gr-x (regno sp))) + (set (raw-reg h-gr-x (regno sp)) (raw-reg h-sr-x (regno usp))) + (set (raw-reg BI h-ubit-x) val) + (c-call VOID "@cpu@_usermode_enabled"))))) +) + +(define-hardware + (semantic-name h-ibit-x) + (name h-ibit-v32) + (comment "Interrupt-enable bit") + (attrs MACH-V32) + (type register BI) + (set + (val) + (sequence + () + (if (not (reg BI h-ubit)) + (sequence + ((BI enabled)) + (set enabled (andif val (not (raw-reg BI h-ibit-x)))) + (set (raw-reg BI h-ibit-x) val) + ; Call handler when enabling. + (if enabled (c-call VOID "@cpu@_interrupts_enabled")))))) +) + +(define-hardware + (name h-mbit) + (comment "NMI enable bit") + (attrs MACH-V32) + (type register BI) + (set + (val) + (sequence + () + ; Don't allow clearing (through this handler) when once set. + (if (andif val (andif (not (raw-reg BI h-mbit)) (not (reg BI h-ubit)))) + (sequence + () + (set (raw-reg BI h-mbit) 1) + ; Call handler when enabling. + (c-call VOID "@cpu@_nmi_enabled"))))) +) + +(define-pmacro + (dsh-cond-bit-v32 x-name x-comment x-cond) + "dsh bit for MACH-V32, with bit only changeable when X-COND" + (define-hardware + (name x-name) + (comment x-comment) + (attrs MACH-V32) + (type register BI) + (set (val) (sequence () (if x-cond (set (raw-reg BI x-name) val))))) +) +(define-pmacro + (dsh-protected-bit-v32 x-name x-comment) + "dsh bit for MACH-V32, with bit only changeable in kernel mode" + (dsh-cond-bit-v32 x-name x-comment (not (reg BI h-ubit))) +) +(dsh-protected-bit-v32 h-qbit "Pending single-step bit") + +(define-hardware + (name h-sbit) + (comment "Cause single step exception on ... [see CRISv32 ref] bit") + (attrs MACH-V32) + (type register BI) + (set + (val) + (sequence + () + (if (not (reg BI h-ubit)) + (sequence + ((BI enabled)) + (set enabled (andif val (not (raw-reg BI h-sbit)))) + (set (raw-reg BI h-sbit) val) + ; Call handler when enabling. + (if enabled (c-call VOID "@cpu@_single_step_enabled")))))) +) + +(dnop cbit "" (SEM-ONLY) h-cbit f-nil) +(dnop cbit-move + "cbit for pre-V32, nothing for newer" (SEM-ONLY) h-cbit-move f-nil) +(dnop vbit "" (SEM-ONLY) h-vbit f-nil) +(dnop vbit-move + "vbit for pre-V32, nothing for newer" (SEM-ONLY) h-vbit-move f-nil) +(dnop zbit "" (SEM-ONLY) h-zbit f-nil) +(dnop zbit-move + "zbit for pre-V32, nothing for newer" (SEM-ONLY) h-zbit-move f-nil) +(dnop nbit "" (SEM-ONLY) h-nbit f-nil) +(dnop nbit-move + "nbit for pre-V32, nothing for newer" (SEM-ONLY) h-nbit-move f-nil) +(dnop xbit "" (SEM-ONLY) h-xbit f-nil) +(dnop ibit "" (SEM-ONLY) h-ibit f-nil) +(dnop ubit "" (SEM-ONLY (MACH crisv10,crisv32)) h-ubit f-nil) +(dnop pbit "" (SEM-ONLY (MACH crisv10,crisv32)) h-pbit f-nil) +(dnop + rbit "carry bit for MCP+restore-P flag bit" (SEM-ONLY MACH-V32) h-rbit f-nil) +(dnop sbit "" (SEM-ONLY MACH-V32) h-sbit f-nil) +(dnop mbit "" (SEM-ONLY MACH-V32) h-mbit f-nil) +(dnop qbit "" (SEM-ONLY MACH-V32) h-qbit f-nil) + +(cris-d-hwreg h-insn-prefixed-p BI) +(cris-dsh + h-insn-prefixed-p-x + h-insn-prefixed-p-pre-v32 + "instruction-is-prefixed bit" + (MACH-PRE-V32) + (register BI) +) + +; CRISv32 has no prefixing on memory accesses. CGEN-FIXME: [Once (eq-attr +; (current-mach) ...) works]: can we change andif and/or orif so it +; doesn't look too close at short-circuited operands and avoid defining an +; operand that doesn't apply to a certain mach? +(define-hardware + (semantic-name h-insn-prefixed-p-x) + (name h-insn-prefixed-p-v32) + (attrs MACH-V32 VIRTUAL) + (comment "instruction-is-prefixed bit") + (type register BI) + (get () (const BI 0)) + (set (val) (nop)) +) +(dnop + prefix-set + "Instruction-prefixed flag" + (SEM-ONLY) + h-insn-prefixed-p + f-nil +) + +(cris-dsh + h-prefixreg h-prefixreg-pre-v32 + "Prefix-address register" (MACH-PRE-V32) (register SI)) +(define-hardware + (semantic-name h-prefixreg) + (name h-prefixreg-v32) + (comment "Prefix-address register, redirecting to ACR") + (attrs MACH-V32 VIRTUAL) + (type register SI) + ; Why can't we have just a "acr" a.k.a "(reg h-gr 15)" here? + (get () acr) + (set (value) (set acr value)) +) + +(dnop + prefixreg + "Prefix address" + (SEM-ONLY) + h-prefixreg + f-nil +) + +;;;;;;;;;;;;;;;;;; -ifield + +; 15 0 +; +-----------+-----+-----------+-----+-----------+ +; | Operand2 | Mode| Opcode | Size| Operand1 | +; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +; +; Figure 5. General instruction format. +; +; Some deviations from this format exist, [see below]. + +; Field specifiers in CGEN specify the highest numbered bit followed by +; the number of bits. + +(dnf f-operand1 "Operand1" () 3 4) +(dnf f-size "Size" () 5 2) +(dnf f-opcode "Opcode" () 9 4) +(dnf f-mode "Mode" () 11 2) +(dnf f-operand2 "Operand2" () 15 4) + +; Subfields. FIXME: unfortunately there's some limitation in CGEN so we +; can't (as would be somewhat intuitive) make f-mode a multi-ifield +; consisting of these two, concatenated. +(dnf f-memmode "Indirect of autoincrement" () 10 1) +(dnf f-membit "Memory specifier" () 11 1) + +(dnf f-b5 "Bit 5 (zero for some quick operands)" () 5 1) + +; When the addressing mode is quick immediate, the low bits are +; part of the operand. +(dnf f-opcode-hi "Opcode field, high bits" () 9 2) + +; Common synonyms for those fields. +(define-pmacro f-source f-operand1) +(define-pmacro f-dest f-operand2) + +(dnmf + f-dstsrc "Dest and source fields concatenated" () UINT + (f-dest f-source) + ; Insert-code. + (sequence + ((SI tmpval)) + (set tmpval (ifield f-dstsrc)) + (set (ifield f-dest) (and (srl tmpval 4) #xf)) + (set (ifield f-source) (and tmpval #xf))) + ; Extract-code. + (set + (ifield f-dstsrc) + (and (or (ifield f-source) (sll (ifield f-dest) 4)) #xff)) +) + +;The 6-bit value may be sign or zero extended depending on the instruction. +; +; 15 0 +; +-----------+-----+-----------+-----+-----------+ +; | Operand2 | Mode| Opcode | Immediate value | +; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +; +; Figure 6. Quick immediate addressing mode instruction format. + +(dnf f-u6 "Quick immediate unsigned 6-bit" () 5 6) +(df f-s6 "Quick signed 6-bit" () 5 6 INT #f #f) + +; There's also a variant used with shift insns, with one bit larger opcode +; and one bit smaller immediate value, though it doesn't have a general +; graphic description. +(dnf f-u5 "Quick unsigned 5-bit" () 4 5) + +; Similarly, a four-bit immediate field. +(dnf f-u4 "Quick unsigned 4-bit" () 3 4) + +; An 8-bit signed value, which doesn't have a general graphic description. +(df f-s8 "Source signed byte" () 7 8 INT #f #f) + +; The 9-bit branch offset, with bit 0 in the field being bit 8 in the +; offset, and bit 0 in the offset always 0. +(df f-disp9-hi "PC-relative 9-bit offset, sign bit" () 0 1 INT #f #f) +(dnf f-disp9-lo "PC-relative 9-bit offset, low bits" () 7 7) + +; It would work to have this in two mach-specific variants, but +; considering that current-mach-is-v32 is a compile-time constant, we +; don't win any simulator performance. +(dnmf + f-disp9 "PC-relative 9-bit offset" + (PCREL-ADDR) + INT + (f-disp9-hi f-disp9-lo) + ; Insert-code. + (sequence + ((SI absval)) + (set absval (srl (sub (sub SI (ifield f-disp9) pc) + (if SI current-mach-is-v32 0 2)) 1)) + (set (ifield f-disp9-hi) (if (lt absval 0) 1 0)) + (set (ifield f-disp9-lo) (and absval) #x7f)) + ; Extract-code. + (sequence + ((SI abslo) (SI absval)) + (set abslo (sll (ifield f-disp9-lo) 1)) + (set absval + (or (if SI (ne (ifield f-disp9-hi) 0) + (inv SI #xff) + 0) + abslo)) + (set (ifield f-disp9) + (add SI (add SI pc absval) (if SI current-mach-is-v32 0 2)))) +) + +; The operand of LAPCQ is PC-relative, similar to f-disp9 but unsigned, +; and only four bits. +(df + f-qo + "PC-relative 4-bit unsigned offset, counted from start of insn" + (MACH-V32 PCREL-ADDR) + 3 4 + UINT + ; Insert-code. + ((value pc) (srl SI (sub SI value pc) 1)) + ; Extract-code. + ((value pc) (add SI pc (sll SI value 1))) +) + +; 8-bit, 16-bit and 32-bit immediates. The 8-bit values are constructed +; through encoding/decoding functions, since the PC increment is by a +; word. +(define-pmacro (dcrisf x-name x-comment x-attrs x-word-offset x-word-length + x-start x-length x-mode x-encode x-decode) + (define-ifield + (name x-name) + (comment x-comment) + (.splice attrs (.unsplice x-attrs)) + (word-offset x-word-offset) + (word-length x-word-length) + (start x-start) + (length x-length) + (mode x-mode) + (.splice encode (.unsplice x-encode)) + (.splice decode (.unsplice x-decode)) + ) +) + +(dcrisf + f-indir-pc+-byte "[PC+] 8-bit field" (SIGN-OPT) + 16 16 + 15 16 ; CGEN-FIXME: Should be 7 8 + INT (#f) (#f) +) + +(dcrisf + f-indir-pc+-word "[PC+] 16-bit field" (SIGN-OPT) + 16 16 15 16 INT (#f) (#f) +) + +; CGEN-FIXME: I shouldn't have to use trunc here, should I? +; Sign-extension should be implicit through use of SI (as opposed to USI) +; and additionally through SIGN-OPT. The ext isn't actually needed, but +; having it there rather than implicit makes more sense than to just have +; the trunc. +(dcrisf + f-indir-pc+-word-pcrel "[PC+] PC-relative 16-bit field" + (PCREL-ADDR SIGN-OPT) + 16 16 15 16 SI + ((value pc) (sub SI value (add SI pc (if SI current-mach-is-v32 0 4)))) + ((value pc) (add SI (ext SI (trunc HI value)) (add SI pc (if SI current-mach-is-v32 0 4)))) +) + +(dcrisf + f-indir-pc+-dword "PC autoincrement - 32-bit field" (SIGN-OPT) + 16 32 31 32 INT (#f) (#f) +) + +(dcrisf + f-indir-pc+-dword-pcrel + "[PC+] PC-relative 32-bit field, counted from start of insn" + (SIGN-OPT MACH-V32 PCREL-ADDR) + 16 32 31 32 INT + ((value pc) (sub SI value pc)) + ((value pc) (add SI pc value)) +) + +;;;;;;;;;;;;;;;;;; -insn-enum -normal-operand -normal-derived-operand + +;; How different fields are transformed into something we put in insns. + +; m := size modifier, byte (00), word (01) or dword (10) +; z := size modifier, byte (0) or word (1) +; (For the latter, the "higher" bit is always 0, mapping trivially on m.) + +(define-normal-insn-enum + insn-size + "Standard instruction operand size" + () + SIZE_ + f-size + ("BYTE" "WORD" "DWORD" "FIXED") +) + +; The mode field for insns with "s" operand (perhaps with a partial set of +; operand types). +(define-normal-insn-enum + insn-mode + "Standard instruction addressing modes" + () + MODE_ + f-mode + ("QUICK_IMMEDIATE" "REGISTER" "INDIRECT" "AUTOINCREMENT") +) + +(define-normal-insn-enum + insn-memoryness-mode + "Whether the operand is indirect" + () + MODEMEMP_ + f-membit + ("NO" "YES") +) + +; FIXME: Needed? +(define-normal-insn-enum + insn-memincness-mode + "Whether the indirect operand is autoincrement" + () + MODEINCP_ + f-memmode + ("NO" "YES") +) + +; Special semantics for multiply. +(define-pmacro MODE_MULU MODE_INDIRECT) +(define-pmacro MODE_MULS MODE_AUTOINCREMENT) + +(define-normal-insn-enum + insn-signed-size + "Signed instruction operand size" + () + SIGNED_ + f-size + ("UNDEF_SIZE_0" "UNDEF_SIZE_1" "BYTE" "WORD") +) + +(define-normal-insn-enum + insn-unsigned-size + "Unsigned instruction operand size" + () + UNSIGNED_ + f-size + ("BYTE" "WORD" "UNDEF_SIZE_2" "UNDEF_SIZE_3") +) + +; Rs := source operand, register addressing mode +(dnop Rs "Source general register" () h-gr f-source) + +; [Rs] := source operand, indirect addressing mode +; = MODE_INDIRECT Rs + +; [Rs+] := source operand, autoincrement addressing mode (see note!) +; = MODE_AUTOINCREMENT Rs + +; The union of [Rs] and [Rs(+)] +; = MODEMEMP_YES Rs + +; Whether an indirect operand is increment can be obtained as an operand by +; = inc +(dnop inc "Incrementness of indirect operand" () h-inc f-memmode) + +; or as an affirmative specifier +; = MODEINCP_YES +; (or MODEINCP_NO) + +; s := source operand, any of the modes Rs, [Rs] or [Rs+] +; No common operand; each are handled separately, using the above definitions. + +; Ps := source operand, special register +; It's in the field usually used for the destination. +(dnop Ps "Source special register" () h-sr f-dest) + +; Ss := source operand, support register +; It's in the field usually used for the destination. +(dnop Ss "Source support register" (MACH-V32) h-supr f-dest) + +; Sd := source operand, support register +(dnop Sd "Destination support register" (MACH-V32) h-supr f-dest) + +; i := 6-bit signed immediate operand +(dnop i "Quick signed 6-bit" () h-sint f-s6) + +; j := 6-bit unsigned immediate operand +(dnop j "Quick unsigned 6-bit" () h-uint f-u6) + +; c := 5-bit immediate shift value +(dnop c "Quick unsigned 5-bit" () h-uint f-u5) + +; qo := 4-bit unsigned immediate operand +(dnop qo "Quick unsigned 4-bit, PC-relative" (MACH-V32) h-addr f-qo) + +; Rd := destination operand, register addressing mode +(dnop Rd "Destination general register" () h-gr f-dest) +(define-pmacro Rd-sfield Rs) +(define-pmacro Rs-dfield Rd) + +; [Rd] := destination operand, indirect addressing mode +; = MODE_INDIRECT Rd + +; [Rd+] := destination operand, autoincrement addressing mode +; = MODE_AUTOINCREMENT Rd + +; [PC+] := destination operand PC, autoincrement addressing mode +; = MODE_AUTOINCREMENT (f-dest 15) X +; where X is one of sconst8, uconst8, sconst16, uconst16 or const32. +(dnop sconst8 "Signed byte [PC+]" () h-sint f-indir-pc+-byte) +(dnop uconst8 "Unsigned byte [PC+]" () h-uint f-indir-pc+-byte) +(dnop sconst16 "Signed word [PC+]" () h-sint f-indir-pc+-word) +(dnop uconst16 "Unsigned word [PC+]" () h-uint f-indir-pc+-word) +(dnop const32 "Dword [PC+]" () h-uint f-indir-pc+-dword) +(dnop const32-pcrel "Dword [PC+]" () h-addr f-indir-pc+-dword-pcrel) + +; d := destination operand, any of the modes Rd, [Rd] or [Rd+] +; No common operand; each are handled separately, using the above definitions. + +; Pd := destination operand, special register +(dnop Pd "Destination special register" () h-sr f-dest) + +; o := 8-bit immediate offset value +(dnop o "Signed 8-bit" () h-sint f-s8) + +; The division of operand semantics and insn fields in the CRIS +; instruction set reference doesn't permit a simple mapping to a +; simulator description, and the division of insn fields and +; semantics in CGEN is not between the define-normal-ifield +; vs. define-normal-operand. For example, the "o" operand is +; PC-relative for branch insns, as described by the CGEN f-disp9 +; field. +; See comment at f-disp9; thankfully the mach +; attribute works here to have two different definitions by the +; same name. +(dnop o-pcrel "9-bit signed immediate PC-rel" + () + h-iaddr f-disp9) + +(dnop o-word-pcrel "16-bit signed immediate PC-rel" + () + h-iaddr f-indir-pc+-word-pcrel) + +; cc := condition code +(dnop cc "Condition codes" () h-ccode f-dest) + +; n := 4 bit breakpoint exception vector index +(dnop n "Quick unsigned 4-bit" () h-uint f-u4) + +; The "option" in the SWAP insn. +(dnop swapoption "Swap option" () h-swap f-dest) + +(dnop list-of-flags "Flag bits as operand" () h-flagbits f-dstsrc) + +; Enumerations for insn codes, for use in insn definitions +; instead of raw numbers. See it as operand definitions for the +; opcode field. + +(define-normal-insn-enum + insn-qi-opc + "Insns for MODE_QUICK_IMMEDIATE" + () + Q_ + f-opcode + ("BCC_0" "BCC_1" "BCC_2" "BCC_3" + "BDAP_0" "BDAP_1" "BDAP_2" "BDAP_3" + "ADDQ" "MOVEQ" "SUBQ" "CMPQ" + "ANDQ" "ORQ" "ASHQ" "LSHQ") +) + +(define-normal-insn-enum + insn-qihi-opc + "Same as insn-qi-opc, though using only the high two bits of the opcode" + () + QHI_ + f-opcode-hi + ("BCC" "BDAP" "OTHER2" "OTHER3") +) +(define-pmacro QHI_ADDOQ QHI_BDAP) + +(define-normal-insn-enum + insn-r-opc + "Insns for MODE_REGISTER and either SIZE_BYTE, SIZE_WORD or SIZE_DWORD" + () + R_ + f-opcode + ("ADDX" "MOVX" "SUBX" "LSL" + "ADDI" "BIAP" "NEG" "BOUND" + "ADD" "MOVE" "SUB" "CMP" + "AND" "OR" "ASR" "LSR") +) +(define-pmacro R_ADDI_ACR R_BIAP) + +(define-normal-insn-enum + insn-rfix-opc + "Insns for MODE_REGISTER and SIZE_FIXED" + () + RFIX_ + f-opcode + ("ADDX" "MOVX" "SUBX" "BTST" + "SCC" "ADDC" "SETF" "CLEARF" + "MOVE_R_S" "MOVE_S_R" "ABS" "DSTEP" + "LZ" "SWAP" "XOR" "MSTEP") +) +(define-pmacro RFIX_MCP RFIX_MSTEP) + +(define-normal-insn-enum + insn-indir-opc + "Insns for (MODE_INDIRECT or MODE_AUTOINCREMENT) and either SIZE_BYTE, SIZE_WORD or SIZE_DWORD" + () + INDIR_ + f-opcode + ("ADDX" "MOVX" "SUBX" "CMPX" + "MUL" "BDAP_M" "ADDC" "BOUND" + "ADD" "MOVE_M_R" "SUB" "CMP" + "AND" "OR" "TEST" "MOVE_R_M") +) +(define-pmacro INDIR_ADDO INDIR_BDAP_M) + +(define-normal-insn-enum + insn-infix-opc + "Insns for (MODE_INDIRECT or MODE_AUTOINCREMENT) and SIZE_FIXED" + () + INFIX_ + f-opcode + ("ADDX" "MOVX" "SUBX" "CMPX" + "JUMP_M" "DIP" "JUMP_R" "BCC_M" + "MOVE_M_S" "MOVE_S_M" "BMOD" "BSTORE" + "RBF" "SBFS" "MOVEM_M_R" "MOVEM_R_M") +) + +(define-pmacro INFIX_MOVE_SS INFIX_SBFS) +(define-pmacro INFIX_LAPC INFIX_DIP) +(define-pmacro INFIX_RFE INFIX_JUMP_M) +(define-pmacro INFIX_RFN INFIX_JUMP_M) +(define-pmacro INFIX_HALT INFIX_JUMP_M) +(define-pmacro INFIX_SFE INFIX_JUMP_M) +(define-pmacro INFIX_RFG INFIX_JUMP_M) +(define-pmacro INFIX_JAS_R INFIX_JUMP_R) +(define-pmacro INFIX_JAS_M INFIX_JUMP_R) +(define-pmacro INFIX_JASC INFIX_RBF) +(define-pmacro INFIX_JUMP_P INFIX_BCC_M) +(define-pmacro INFIX_BAS INFIX_BMOD) +(define-pmacro INFIX_BASC INFIX_BSTORE) +(define-pmacro INFIX_BREAK INFIX_JUMP_M) +(define-pmacro INFIX_FIDXI INFIX_JUMP_M) +(define-pmacro INFIX_FIDXD INFIX_BAS) +(define-pmacro INFIX_FTAGI INFIX_JUMP_M) +(define-pmacro INFIX_FTAGD INFIX_BAS) + +; Classes of insns: +; Move-to-register, move-to-memory, move-to/from-other-register, +; logical, arithmetic, branch. +; Classes of operands: +; quick, register, memory-indirect, memory-postinc. + + +;;;;;;;;;;;;;;;;;; -normal-insn + +(define-pmacro (dni-bwd-attr name comment attr syntax fmt fsem timing) + (begin + (dni (.sym name .b) (.str "byte " comment) attr (.str name ".b " syntax) + (.splice (.unsplice fmt) SIZE_BYTE) + (fsem QI) + timing) + (dni (.sym name .w) (.str "word " comment) attr (.str name ".w " syntax) + (.splice (.unsplice fmt) SIZE_WORD) + (fsem HI) + timing) + (dni (.sym name .d) (.str "dword " comment) attr (.str name ".d " syntax) + (.splice (.unsplice fmt) SIZE_DWORD) + (fsem SI) + timing)) +) + +(define-pmacro (dni-cdt-attr name comment attr syntax fmt semantics) + "dni without specifying timing" + (dni name comment attr syntax fmt semantics (cris-timing)) +) + +(define-pmacro (dni-cdt-bwd-attr name comment attr syntax fmt fsem) + (begin + (dni-cdt-attr (.sym name .b-r) (.str "byte " comment) attr (.str name ".b " syntax) + (.splice (.unsplice fmt) SIZE_BYTE) + (fsem QI)) + (dni-cdt-attr (.sym name .w-r) (.str "word " comment) attr (.str name ".w " syntax) + (.splice (.unsplice fmt) SIZE_WORD) + (fsem HI)) + (dni-cdt-attr (.sym name .d-r) (.str "dword " comment) attr (.str name ".d " syntax) + (.splice (.unsplice fmt) SIZE_DWORD) + (fsem SI))) +) + +; Some convenience macros based on the above ones. +(define-pmacro (dni-cdt-bwd name comment syntax fmt fsem) + (dni-cdt-bwd-attr name comment () syntax fmt fsem) +) + +(define-pmacro (dni-bwd name comment syntax fmt fsem timing) + (dni-bwd-attr comment () syntax fmt fsem timing) +) + +(define-pmacro-map + (((dni-cdt name comment syntax fmt semantics) + (dni-cdt-attr name comment () syntax fmt semantics)) + ((dni-c-QI-attr name comment attr syntax fmt fsem) + (dni name comment attr syntax fmt fsem (cris-timing-const-QI))) + ((dni-c-HI-attr name comment attr syntax fmt fsem) + (dni name comment attr syntax fmt fsem (cris-timing-const-HI))) + ((dni-c-SI-attr name comment attr syntax fmt fsem) + (dni name comment attr syntax fmt fsem (cris-timing-const-SI)))) +) + +(define-pmacro-map + (((dni-c-QI name comment syntax fmt fsem) + (dni-c-QI-attr name comment () syntax fmt fsem)) + ((dni-c-HI name comment syntax fmt fsem) + (dni-c-HI-attr name comment () syntax fmt fsem)) + ((dni-c-SI name comment syntax fmt fsem) + (dni-c-SI-attr name comment () syntax fmt fsem))) +) + +; These flags are both cleared by all insns except prefixes (before +; CRISv32) and "setf x", so we put them in a handy macro. +(define-pmacro + (reset-x-p) + (sequence + () + (set xbit 0) + (set prefix-set 0)) +) + +; NOP | 0 0 0 0| 0 1| 0 1 0 0| 0 0| 1 1 1 1| +; (For V32, "SETF" (no flags) is used.) +(dni-cdt-attr + nop "nop" (MACH-PC) "nop" + (+ (f-operand2 0) R_ADDI MODE_REGISTER SIZE_BYTE (f-operand1 15)) + (reset-x-p) +) + +; Pre- and v32+ variants MOVE insns set flags differently. These two +; macros for flag settings are meant to be used in all MOVE insns. +(define-pmacro (setf-moveq value) + (sequence + () + (set-quiet nbit-move (lt SI value 0)) + (set-quiet zbit-move (andif BI (eq SI value 0) (if BI xbit zbit 1))) + (set-quiet cbit-move 0) + (set-quiet vbit-move 0) + (reset-x-p)) +) + +(define-pmacro (setf-move size value) + (sequence + () + (set nbit (lt size value 0)) + (set zbit (andif BI (eq size value 0) (if BI xbit zbit 1))) + (set-quiet cbit-move 0) + (set-quiet vbit-move 0) + (reset-x-p)) +) +; The CGEN binop-with-bit operations are not documented well enough that I +; trust their semantics to remain stable. Better define local ones: the +; semantics become explicit. +(define-pmacro-map + (((add-overflow size R D S carry) + (orif BI (andif BI (andif BI (lt size S 0) (lt size D 0)) (ge size R 0)) + (andif BI (andif BI (ge size S 0) (ge size D 0)) (lt size R 0)))) + ((add-carry size R D S carry) + (orif BI (andif BI (lt size S 0) (lt size D 0)) + (orif BI (andif BI (lt size D 0) (ge size R 0)) + (andif BI (lt size S 0) (ge size R 0))))) + ((sub-overflow size R D S carry) + (orif BI (andif BI (andif BI (ge size S 0) (lt size D 0)) (ge size R 0)) + (andif BI (andif BI (lt size S 0) (ge size D 0)) (lt size R 0)))) + ((sub-carry size R D S carry) + (orif BI (andif BI (lt size S 0) (ge size D 0)) + (orif BI (andif BI (ge size D 0) (lt size R 0)) + (andif BI (lt size S 0) (lt size R 0))))) + ; Only valid for size := DI + ((mulu-overflow size R D S carry) + (ne DI R (zext DI (trunc SI R)))) + ((mulu-carry size R D S carry) + (andif current-mach-is-v32 carry)) + ((muls-overflow size R D S carry) + (ne DI R (ext DI (trunc SI R)))) + ((muls-carry size R D S carry) + (andif current-mach-is-v32 carry))) +) + +(define-pmacro (setf-arit2 size op source1 source2 result carryin carryout) + "Set no-prefix, x=0, carryout, v, z and n according to operation OP in size SIZE" + (sequence + () + (set carryout ((.sym op -carry) size result source1 source2 carryin)) + (set nbit (lt size result 0)) + (set zbit (andif BI (eq size result 0) (orif BI zbit (not BI xbit)))) + (set vbit ((.sym op -overflow) size result source1 source2 carryin)) + (reset-x-p)) +) +(define-pmacro (setf-arit size op source1 source2 result carry) + "Set no-prefix, x=0, c, v, z and n according to operation OP in size SIZE" + (setf-arit2 size op source1 source2 result carry cbit) +) + +; Let's have convienence macros for arithmetic, including evaluation of the +; operation, destination modification, flag setting and carry propagation. +(define-pmacro + (cris-arit6-int arit size fdest fdest_op srcop1 srcop2 carryout carryin) + "Core for performing some three-operand arithmetic with carry as parameter" + (sequence + ((size tmpopd) (size tmpops) (BI carry) (size newval)) + (set tmpops srcop2) + (set tmpopd srcop1) + (set carry carryin) + (set newval ((.sym arit c) tmpopd tmpops (if BI (eq xbit 0) 0 carry))) + (fdest size fdest_op newval) + (setf-arit2 size arit tmpopd tmpops newval carry carryout)) +) + +(define-pmacro + (cris-arit5-int arit size destregno srcop1 srcop2 carryout carryin) + "As cris-arit6-int, but to set a part of a general register" + (cris-arit6-int + arit + size + (.pmacro (sz regno val) (set-subreg-gr sz regno val)) + destregno + srcop1 + srcop2 + carryout + carryin) +) + +(define-pmacro (cris-arit5 arit size destreg srcop1 srcop2 carryout carryin) + "As cris-arit5-int, but takes a register as parameter, not register number" + (cris-arit5-int arit size (regno destreg) srcop1 srcop2 carryout carryin) +) +(define-pmacro (cris-arit3-int arit size destregno srcop1 srcop2) + "As cris-arit5-int, but with carry-in same as carry-out" + (cris-arit5-int arit size destregno srcop1 srcop2 cbit cbit) +) +(define-pmacro (cris-arit3 arit size destreg srcop1 srcop2) + "As cris-arit3-int, but takes a register as parameter, not register number" + (cris-arit3-int arit size (regno destreg) srcop1 srcop2) +) +(define-pmacro (cris-arit arit size destreg srcop) + "As cris-arit3, but with destination same as srcop1" + (cris-arit3 arit size destreg destreg srcop) +) +(define-pmacro (cris-arit-3op arit size destsrcop2 srcop1 dest-3op) + "Similar to cris-arit3-int, but for prefixed operand only" + (cris-arit3-int arit size + (if SI (andif prefix-set (not inc)) + (regno dest-3op) + (regno destsrcop2)) + destsrcop2 srcop1) +) + +; Convenience macros to select a part of a value and its complement, for +; the <op>.b, <op>.w and <op>.d operations. +(define-pmacro (QI-part val) (and SI val #xff)) +(define-pmacro (non-QI-part val) (and SI val #xffffff00)) +(define-pmacro (HI-part val) (and SI val #xffff)) +(define-pmacro (non-HI-part val) (and SI val #xffff0000)) +(define-pmacro (SI-part val) val) +(define-pmacro (non-SI-part val) 0) +(define-pmacro + (set-subreg-gr-bw BWD gregno newval) + "Set a byte or word part or full dword of a general register" + (sequence + ((SI oldregval)) + (set oldregval (reg h-raw-gr gregno)) + (set (reg h-gr gregno) + (or SI ((.sym BWD -part) newval) ((.sym non- BWD -part) oldregval)))) +) +(define-pmacro (set-subreg-gr BWD gregno newval) + ((.sym set-subreg-gr- BWD) BWD gregno newval) +) +(define-pmacro (set-subreg-gr-SI SI gregno newval) + (set (reg h-gr gregno) newval) +) +(define-pmacro set-subreg-gr-HI set-subreg-gr-bw) +(define-pmacro set-subreg-gr-QI set-subreg-gr-bw) + +; MOVE.m Rs,Rd [ Rd | 011001mm | Rs ] +(dni-cdt-bwd + move "move.m r,R" + "move.m ${Rs},${Rd}" + (+ Rd MODE_REGISTER R_MOVE Rs) + (.pmacro + (BWD) + (sequence + ((BWD newval)) + (set newval Rs) + (set-subreg-gr BWD (regno Rd) newval) + (setf-move BWD newval))) +) + +; MOVE.D PC,Rd [ Rd | 01100110 | 1111 ] +; This insn is used in PIC code to find out the code address. It's an +; exception to the (guarded) non-implementation of PC operands in this +; file. +(dni-cdt-attr + movepcr "move.d PC,R" + (MACH-PC UNCOND-CTI) + "move.d PC,${Rd}" + (+ Rd MODE_REGISTER R_MOVE SIZE_DWORD (f-source 15)) + (sequence + ((SI pcval)) + (set pcval (add SI pc 2)) + (set Rd pcval) + (setf-move SI pcval)) +) + +; MOVEQ i,Rd [ Rd | 001001 | i ] +(dni-cdt + moveq "moveq" + "moveq $i,$Rd" + (+ Rd MODE_QUICK_IMMEDIATE Q_MOVEQ i) + (sequence + ((SI newval)) + (set newval i) + (set Rd newval) + (setf-moveq newval)) +) + +(define-pmacro (dni-cdt-sbw name comment syntax fmt fsem) + "Insn generator for insns with signed <op>.b and <op>.w variants" + (begin + (dni-cdt + (.sym name .b-r) (.str "byte " comment) (.str name ".b " syntax) + (.splice (.unsplice fmt) SIGNED_BYTE) + (fsem QI)) + (dni-cdt + (.sym name .w-r) (.str "word " comment) (.str name ".w " syntax) + (.splice (.unsplice fmt) SIGNED_WORD) + (fsem HI))) +) + +; MOVS.z Rs,Rd [ Rd | 0100011z | Rs ] +(dni-cdt-sbw + movs "movs.m r,R" + "movs.m ${Rs},${Rd}" + (+ Rd MODE_REGISTER R_MOVX Rs) + (.pmacro + (BW) + (sequence + ((BW tmpops) (SI newval)) + (set tmpops Rs) + (set newval (ext SI tmpops)) + (set Rd newval) + (setf-move SI newval))) +) + +(define-pmacro (dni-cdt-ubw name comment syntax fmt fsem) + "Similar to dni-cdt-sbw but for unsigned operations" + (begin + (dni-cdt + (.sym name .b-r) (.str "byte " comment) (.str name ".b " syntax) + (.splice (.unsplice fmt) UNSIGNED_BYTE) + (fsem QI)) + (dni-cdt + (.sym name .w-r) (.str "word " comment) (.str name ".w " syntax) + (.splice (.unsplice fmt) UNSIGNED_WORD) + (fsem HI))) +) + +; MOVU.z Rs,Rd [ Rd | 0100010z | Rs ] +(dni-cdt-ubw + movu "movu.m r,R" + "movu.m ${Rs},${Rd}" + (+ Rd MODE_REGISTER R_MOVX Rs) + (.pmacro + (BW) + (sequence + ((BW tmpops) (SI newval)) + (set tmpops Rs) + (set newval (zext SI tmpops)) + (set Rd newval) + (setf-move SI newval))) +) + +; (MOVE.m [PC+],Rd [ Rd | 111001mm | 1111 ]) +; For the moment, it doesn't seem worthwhile to make a dni-c-bwd macro; +; too many places to parametrize. +(dni-c-QI + movecbr "move.b [PC+],R" + "move.b ${sconst8},${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_MOVE_M_R SIZE_BYTE (f-source 15) sconst8) + (sequence + ((QI newval)) + (set newval sconst8) + (set-subreg-gr QI (regno Rd) newval) + (setf-move QI newval)) +) + +(dni-c-HI + movecwr "move.w [PC+],R" + "move.w ${sconst16},${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_MOVE_M_R SIZE_WORD (f-source 15) sconst16) + (sequence + ((HI newval)) + (set newval sconst16) + (set-subreg-gr HI (regno Rd) newval) + (setf-move HI newval)) +) + +(dni-c-SI + movecdr "move.d [PC+],R" + "move.d ${const32},${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_MOVE_M_R SIZE_DWORD (f-source 15) const32) + (sequence + ((SI newval)) + (set newval const32) + (set Rd newval) + (setf-move SI newval)) +) + +; (MOVS.z [PC+],Rd [ Rd | 1100011z | 1111 ]) +; Similarly, no likely net improvement for a dni-c-bw. +(dni-c-QI + movscbr "movs.b [PC+],R" + "movs.b ${sconst8},${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_MOVX SIGNED_BYTE (f-source 15) sconst8) + (sequence + ((SI newval)) + ; FIXME: Make trunc unnecessary. + (set newval (ext SI (trunc QI sconst8))) + (set Rd newval) + (setf-move SI newval)) +) + +(dni-c-HI + movscwr "movs.w [PC+],R" + "movs.w ${sconst16},${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_MOVX SIGNED_WORD (f-source 15) sconst16) + (sequence + ((SI newval)) + ; FIXME: Make trunc unnecessary. + (set newval (ext SI (trunc HI sconst16))) + (set Rd newval) + (setf-move SI newval)) +) + +; (MOVU.z [PC+],Rd [ Rd | 1100010z | 1111 ]) +(dni-c-QI + movucbr "movu.b [PC+],R" + "movu.b ${uconst8},${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_MOVX UNSIGNED_BYTE (f-source 15) uconst8) + (sequence + ((SI newval)) + ; FIXME: Make trunc unnecessary. + (set newval (zext SI (trunc QI uconst8))) + (set Rd newval) + (setf-move SI newval)) +) + +(dni-c-HI + movucwr "movu.w [PC+],R" + "movu.w ${uconst16},${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_MOVX UNSIGNED_WORD (f-source 15) uconst16) + (sequence + ((SI newval)) + ; FIXME: Make trunc unnecessary. + (set newval (zext SI (trunc HI uconst16))) + (set Rd newval) + (setf-move SI newval)) +) + +; ADDQ j,Rd [ Rd | 001000 | j ] +(dni-cdt + addq "addq j,Rd" + "addq $j,$Rd" + (+ Rd MODE_QUICK_IMMEDIATE Q_ADDQ j) + (cris-arit add SI Rd j) +) + +; SUBQ j,Rd [ Rd | 001010| j ] +(dni-cdt + subq "subq j,Rd" + "subq $j,$Rd" + (+ Rd MODE_QUICK_IMMEDIATE Q_SUBQ j) + (cris-arit sub SI Rd j) +) + +; Convenience macros for insns with a memory operand. +(define-pmacro + (dni-cmt-attr-tim name comment attr syntax fmt semantics timing) + "dni with memory-access" + (dni name comment attr syntax + ; Specifying MODE_INDIRECT and MODE_AUTOINCREMENT in this + ; manner makes the autoincrementness handily available. + ; It also effectively excludes non-memory use of dni-cmt. + (.splice (.unsplice fmt) MODEMEMP_YES inc) + semantics + timing) +) + +(define-pmacro (dni-cmt-attr name comment attr syntax fmt semantics) + "dni with read memory-access timing" + (dni-cmt-attr-tim name comment attr syntax fmt semantics + (cris-mem-timing)) +) + +(define-pmacro (dni-cmwt-attr name comment attr syntax fmt semantics) + "dni with write memory-access timing" + (dni-cmt-attr-tim name comment attr syntax fmt semantics + (cris-mem-write-timing)) +) + +(define-pmacro QI-size 1) +(define-pmacro HI-size 2) +(define-pmacro SI-size 4) + +(define-pmacro (cris-get-mem size regop) + "Handle reading memory in <size>, with source address register\ + (read once, maybe set once) in <regop> or prefixed" + (sequence + size + ((SI addr) (size tmp-mem) (BI postinc)) + + ; Cache the incrementness of the operand. + (set postinc inc) + + ; Get the address from somewhere. + (set addr + (if SI (eq prefix-set 0) + ; If the insn was prefixed, it's in the prefix-register. + regop + prefixreg)) + + ; Get the memory contents. + (set tmp-mem (mem size addr)) + + ; For non-prefixed post-increment, we increment the address by the + ; size of the memory access. + (if (ne postinc 0) + (sequence + () + (if (eq prefix-set 0) + (set addr (add addr (.sym size -size)))) + ; Update the source-register for post-increments. + (set regop addr))) + + ; Don't forget the return-value. + tmp-mem) +) + +(define-pmacro (cris-set-mem size regop value) + "Handle writing <value> of <size> to memory, with memory address register\ + (read once, maybe set once) in <regop> or prefixed." + (sequence + ((SI addr) (BI postinc)) + + ; Cache the incrementness of the operand. + (set postinc inc) + + ; Get the address from somewhere. + (set addr + (if SI (eq prefix-set 0) + ; If the insn was prefixed, it's in the prefix-register. + regop + prefixreg)) + + ; Set the memory contents. Integral-write semantics apply. + ; FIXME: currently v32 only; when proper semantics needed, fix v10. + (if (andif current-mach-is-v32 (ne xbit 0)) + (if (eq pbit 0) + (sequence + () + (set (mem size addr) value) + ; Write failures are signalled (by whatever entity "sends + ; the signal") by setting P at time of the write above, if X + ; is set. Here, we just need to copy P into C. + (set cbit pbit)) + (set cbit 1)) + (set (mem size addr) value)) + + ; For non-prefixed post-increment, we increment the address by the + ; size of the memory access. As for the integral-write, this needs to + ; be tweaked for pre-v32: increment should have been performed if + ; there's a fault at the memory access above. + (if (ne postinc 0) + (sequence + () + (if (eq prefix-set 0) + (set addr (add addr (.sym size -size)))) + ; Update the source-register for post-increments. + (set regop addr)))) +) + +(define-pmacro + (dni-cmt-bwd-attr-tim name comment attr syntax fmt fsem timing) + "Core generator macro for insns with <op>.b, <op>.w and <op>.d variants\ + and a memory operand." + (begin + (dni-cmt-attr-tim + (.sym name .b-m) + (.str "byte mem " comment) + attr + (.str name ".b " syntax) + (.splice (.unsplice fmt) SIZE_BYTE) + (fsem QI) + timing) + (dni-cmt-attr-tim + (.sym name .w-m) + (.str "word mem " comment) + attr + (.str name ".w " syntax) + (.splice (.unsplice fmt) SIZE_WORD) + (fsem HI) + timing) + (dni-cmt-attr-tim + (.sym name .d-m) + (.str "dword mem " comment) + attr + (.str name ".d " syntax) + (.splice (.unsplice fmt) SIZE_DWORD) + (fsem SI) + timing)) +) + +; Further refinement macros. +(define-pmacro (dni-cmt-bwd-attr name comment attr syntax fmt fsem) + (dni-cmt-bwd-attr-tim name comment attr syntax fmt fsem + (cris-mem-timing)) +) + +(define-pmacro (dni-cmwt-bwd name comment syntax fmt fsem) + (dni-cmt-bwd-attr-tim name comment () syntax fmt fsem + (cris-mem-write-timing)) +) + +(define-pmacro (dni-cmt-bwd name comment syntax fmt fsem) + (dni-cmt-bwd-attr name comment () syntax fmt fsem) +) + +(define-pmacro (dni-cmt-sbw name comment syntax fmt fsem) + "Core generator macro for insns with <op>.b and <op>.w variants\ + and a signed memory operand." + (begin + (dni-cmt-attr + (.sym name .b-m) (.str "byte mem " comment) + () + (.str name ".b " syntax) + (.splice (.unsplice fmt) SIGNED_BYTE) + (fsem QI)) + (dni-cmt-attr + (.sym name .w-m) (.str "word mem " comment) + () + (.str name ".w " syntax) + (.splice (.unsplice fmt) SIGNED_WORD) + (fsem HI))) +) + +(define-pmacro (dni-cmt-ubw name comment syntax fmt fsem) + "Core generator macro for insns with <op>.b and <op>.w variants\ + and an unsigned memory operand." + (begin + (dni-cmt-attr + (.sym name .b-m) (.str "byte mem " comment) + () + (.str name ".b " syntax) + (.splice (.unsplice fmt) UNSIGNED_BYTE) + (fsem QI)) + (dni-cmt-attr + (.sym name .w-m) (.str "word mem " comment) + () + (.str name ".w " syntax) + (.splice (.unsplice fmt) UNSIGNED_WORD) + (fsem HI))) +) + +; CMP.m Rs,Rd [ Rd | 011011mm | Rs ] +(dni-cdt-bwd + cmp-r "compare register to register" + "$Rs,$Rd" + (+ Rd MODE_REGISTER R_CMP Rs) + (.pmacro + (BWD) + (cris-arit6-int + sub BWD (.pmacro (sz regno val) (nop)) 0 + Rd Rs cbit cbit)) +) + +; CMP.m [Rs],Rd [ Rd | 101011mm | Rs ] +; CMP.m [Rs+],Rd [ Rd | 111011mm | Rs ] +(dni-cmt-bwd + cmp-m "compare memory to register" + "[${Rs}${inc}],${Rd}" + (+ INDIR_CMP Rs Rd) + (.pmacro + (BWD) + (cris-arit6-int + sub BWD (.pmacro (sz regno val) (nop)) 0 + Rd (cris-get-mem BWD Rs) cbit cbit)) +) + +; (CMP.m [PC+],Rd [ Rd | 111011mm | 1111 ]) +(dni-c-QI + cmpcbr "cmp constant byte to register" + "cmp.b $sconst8,$Rd" + (+ Rd MODE_AUTOINCREMENT INDIR_CMP SIZE_BYTE (f-source 15) sconst8) + (cris-arit6-int + sub QI (.pmacro (sz regno val) (nop)) 0 + Rd (trunc QI sconst8) cbit cbit) +) + +(dni-c-HI + cmpcwr "cmp constant word to register" + "cmp.w $sconst16,$Rd" + (+ Rd MODE_AUTOINCREMENT INDIR_CMP SIZE_WORD (f-source 15) sconst16) + (cris-arit6-int + sub HI (.pmacro (sz regno val) (nop)) 0 + Rd (trunc HI sconst16) cbit cbit) +) + +(dni-c-SI + cmpcdr "cmp constant dword to register" + "cmp.d $const32,$Rd" + (+ Rd MODE_AUTOINCREMENT INDIR_CMP SIZE_DWORD (f-source 15) const32) + (cris-arit6-int + sub SI (.pmacro (sz regno val) (nop)) 0 + Rd const32 cbit cbit) +) + +; CMPQ i,Rd [ Rd | 001011 | i ] +(dni-cdt + cmpq "cmpq i,Rd" + "cmpq $i,$Rd" + (+ Rd MODE_QUICK_IMMEDIATE Q_CMPQ i) + (cris-arit6-int + sub SI (.pmacro (sz regno val) (nop)) 0 + Rd i cbit cbit) +) + +; CMPS.z [Rs],Rd [ Rd | 1000111z | Rs ] +; CMPS.z [Rs+],Rd [ Rd | 1100111z | Rs ] +(dni-cmt-sbw + cmps-m "cmp sign-extended from memory to register" + "[${Rs}${inc}],$Rd" + (+ Rd INDIR_CMPX Rs) + (.pmacro + (BW) + (cris-arit6-int + sub SI (.pmacro (sz regno val) (nop)) 0 + Rd ((.sym BW -ext) (cris-get-mem BW Rs)) cbit cbit)) +) + +; (CMPS.z [PC+],Rd [ Rd | 1100111z | 1111 ]) +(dni-c-QI + cmpscbr "cmp sign-extended constant byte to register" + "[${Rs}${inc}],$Rd" + (+ Rd MODE_AUTOINCREMENT INDIR_CMPX SIGNED_BYTE (f-source 15) sconst8) + (cris-arit6-int + sub SI (.pmacro (sz regno val) (nop)) 0 + Rd (ext SI (trunc QI sconst8)) cbit cbit) +) +(dni-c-HI + cmpscwr "cmp sign-extended constant word to register" + "[${Rs}${inc}],$Rd" + (+ Rd MODE_AUTOINCREMENT INDIR_CMPX SIGNED_WORD (f-source 15) sconst16) + (cris-arit6-int + sub SI (.pmacro (sz regno val) (nop)) 0 + Rd (ext SI (trunc HI sconst16)) cbit cbit) +) + +; CMPU.z [Rs],Rd [ Rd | 1000110z | Rs ] +; CMPU.z [Rs+],Rd [ Rd | 1100110z | Rs ] +(dni-cmt-ubw + cmpu-m "cmp zero-extended from memory to register" + "[${Rs}${inc}],$Rd" + (+ Rd INDIR_CMPX Rs) + (.pmacro + (BW) + (cris-arit6-int + sub SI (.pmacro (sz regno val) (nop)) 0 + Rd ((.sym BW -zext) (cris-get-mem BW Rs)) cbit cbit)) +) + +; (CMPU.z [PC+],Rd [ Rd | 1100110z | 1111 ]) +(dni-c-QI + cmpucbr "cmp zero-extended constant byte to register" + "[${Rs}${inc}],$Rd" + (+ Rd MODE_AUTOINCREMENT INDIR_CMPX UNSIGNED_BYTE (f-source 15) uconst8) + (cris-arit6-int + sub SI (.pmacro (sz regno val) (nop)) 0 + Rd (zext SI (trunc QI uconst8)) cbit cbit) +) +(dni-c-HI + cmpucwr "cmp zero-extended constant word to register" + "[${Rs}${inc}],$Rd" + (+ Rd MODE_AUTOINCREMENT INDIR_CMPX UNSIGNED_WORD (f-source 15) uconst16) + (cris-arit6-int + sub SI (.pmacro (sz regno val) (nop)) 0 + Rd (zext SI (trunc HI uconst16)) cbit cbit) +) + +; MOVE.m [Rs],Rd [ Rd | 101001mm | Rs ] +; MOVE.m [Rs+],Rd [ Rd | 111001mm | Rs ] +(dni-cmt-bwd + move-m "move from memory to register" + "[${Rs}${inc}],${Rd}" + (+ INDIR_MOVE_M_R Rs Rd) + (.pmacro + (BWD) + (sequence + ((SI tmp)) + (set tmp (cris-get-mem BWD Rs)) + (set-subreg-gr + BWD + (if SI (andif prefix-set (not inc)) (regno Rs) (regno Rd)) + tmp) + (setf-move BWD tmp))) +) + +; MOVS.z [Rs],Rd [ Rd | 1000011z | Rs ] +; MOVS.z [Rs+],Rd [ Rd | 1100011z | Rs ] +(dni-cmt-sbw + movs-m "movs from memory to register" + "[${Rs}${inc}],${Rd}" + (+ INDIR_MOVX Rs Rd) + (.pmacro + (BW) + (sequence + ((SI tmp)) + (set tmp (ext SI (cris-get-mem BW Rs))) + (if (andif prefix-set (not inc)) + (set Rs tmp) + (set Rd tmp)) + (setf-move SI tmp))) +) + +; MOVU.z [Rs],Rd [ Rd | 1000010z | Rs ] +; MOVU.z [Rs+],Rd [ Rd | 1100010z | Rs ] +(dni-cmt-ubw + movu-m "movu from memory to register" + "[${Rs}${inc}],${Rd}" + (+ INDIR_MOVX Rs Rd) + (.pmacro + (BW) + (sequence + ((SI tmp)) + (set tmp (zext SI (cris-get-mem BW Rs))) + (if (andif prefix-set (not inc)) + (set Rs tmp) + (set Rd tmp)) + (setf-move SI tmp))) +) + +; MOVE Rs,Pd [ Pd | 01100011 | Rs ] +(.splice + begin + (.unsplice + (.map + (.pmacro + (VER) + (dni + (.sym move-r-spr VER) + "Move from general register to special register" + ((MACH (.sym cris VER))) + "move ${Rs},${Pd}" + (+ RFIX_MOVE_R_S MODE_REGISTER SIZE_FIXED Rs Pd) + (sequence + ((SI tmp) (SI rno)) + (set tmp Rs) + (set rno (regno Pd)) + (cond + ; See reg-sr setter for most of the special-register semantics. + ; The sanity check for known read-only registers is for program + ; debug help; the real insn would be harmless and have no effect. + ; CGEN-FIXME: regno of symbolic h-sr names doesn't work here. + ((orif (orif (eq rno 0) (eq rno 1)) (orif (eq rno 4) (eq rno 8))) + (error "move-r-spr: trying to set a read-only special register")) + (else (set Pd tmp))) + (reset-x-p)) + (cris-reg-sr-timing))) + (cris-cpu-models))) +) + +(define-pmacro (dni-cdt-ver-attr name comment fattr syntax fmt fsem) + "Generator for each MACH, using default timing." + (.splice + begin + (.unsplice + (.map + (.pmacro (v) (dni-cdt-attr name comment (fattr v) syntax fmt (fsem v))) + (cris-cpu-models)))) +) + +; MOVE Ps,Rd [ Ps | 01100111 | Rd ] +; Note that in the insn format, the Rd operand is in the Rs field (the +; Rd field by the definition used everywhere else is the Ps position in +; this insn). +; It gets a little weird here because we can't get this insn into a +; define-pmacro unless we make named pmacros for e.g. a separate attr +; function and a semantics function: a .pmacro can't refer to the +; parameters of the outer define-pmacro. (The manual refers to this as +; not implementing "lexical scoping"). +(.splice + begin + (.unsplice + (.map + (.pmacro + (VER) + (dni-cdt-attr + (.sym move-spr-r VER) + "Move from special register to general register" + ((MACH (.sym cris VER))) + "move ${Ps},${Rd-sfield}" + (+ Ps RFIX_MOVE_S_R MODE_REGISTER SIZE_FIXED Rd-sfield) + (sequence + ((SI grno) (SI prno) (SI newval)) + (set prno (regno Ps)) + ; CGEN-FIXME: Can't use the following and then "grno" below because + ; CGEN will emit a "tmp_grno" *also* in decodev32.c:crisv32f_decode + ; (set grno (regno Rd-sfield)) + (set newval Ps) + (.splice + cond + (.unsplice + (.map + (.pmacro + (r) + ((eq prno (.cadr2 r)) + (set-subreg-gr (.car2 r) (regno Rd-sfield) newval))) + ((.sym cris-implemented-readable-specregs- VER)))) + (else (error "move-spr-r from unimplemented register"))) + (reset-x-p)))) + (cris-cpu-models))) +) + +; MOVE Ps,PC [ Ps | 01100111 | 1111 ] +; The move-special-register-to-pc insns are return-type instructions and +; have to be special-cased to get the delay-slot and avoid being indicated +; as invalid. +(dni-cdt-attr + ret-type + "ret-type" + (MACH-PC) + "ret/reti/retb" + (+ Ps MODE_REGISTER RFIX_MOVE_S_R SIZE_FIXED (f-source 15)) + (sequence + ((SI retaddr)) + (set retaddr Ps) + (reset-x-p) + (delay 1 (set pc retaddr))) +) + +; MOVE [Rs],Pd [ Pd | 10100011 | Rs ] +; MOVE [Rs+],Pd [ Pd | 11100011 | Rs ] +; We make variants that loads constants or memory for each MACH version, +; since each consider some subset of the "special registers" to have +; different sizes. FIXME: Should be able to simplify this. +(.splice + begin + (.unsplice + (.map + (.pmacro + (VER) + (dni + (.sym move-m-spr VER) + "Move from memory to special register" + ((MACH (.sym cris VER))) + "move [${Rs}${inc}],${Pd}" + (+ Pd INFIX_MOVE_M_S MODEMEMP_YES inc SIZE_FIXED Rs) + (sequence + ((SI rno) (SI newval)) + (set rno (regno Pd)) + (.splice + cond + ; No sanity check for constant special register here, since the + ; memory read side-effect or post-increment may be the goal, or + ; for pre-v32 a prefix assignment side-effect. + (.unsplice + (.map + (.pmacro + (r) + ((eq rno (.cadr2 r)) + (set newval ((.sym (.car2 r) -ext) (cris-get-mem (.car2 r) Rs))))) + ((.sym cris-implemented-writable-specregs- VER)))) + (else (error "Trying to set unimplemented special register"))) + (set Pd newval) + (reset-x-p)) + (cris-mem-sr-timing))) + (cris-cpu-models))) +) + +(define-pmacro QI-operand sconst8) +(define-pmacro HI-operand sconst16) +(define-pmacro SI-operand const32) + +(define-pmacro + (cris-move-c-spr VER VERFN) + "Generator for loading constant into special register" + (.splice + begin + (.unsplice + (.map + (.pmacro + (srdef v) + (dni + (.sym move-c-spr v -p (.cadr2 srdef)) + (.str "Move constant to special register p" (.cadr2 srdef)) + ((MACH (.sym cris v))) + (.str "move ${" (.sym (.car2 srdef) -operand) "},${Pd}") + ; We use Pd in semantics without naming it in the format (which + ; would CGEN-FIXME: cause a CGEN error for some reason, likely + ; related to specifying an insn field multiple times). This + ; currently works and is guarded with test-cases (specifically + ; wrt. the timing model) but may need to be tweaked in the future. + ; Note that using instead (ifield f-dest) causes incorrect timing + ; model to be generated; the timing model requires that Pd is set. + (+ (f-dest (.cadr2 srdef)) MODE_AUTOINCREMENT INFIX_MOVE_M_S SIZE_FIXED + (f-source 15) (.sym (.car2 srdef) -operand)) + (sequence + () + (set Pd (.sym (.car2 srdef) -operand)) ; (reg h-sr (.cadr2 srdef)) + (reset-x-p)) + ((.sym cris-timing-const-sr- (.car2 srdef))))) + ((.sym cris-implemented-specregs-const- VER)) + (.map VERFN ((.sym cris-implemented-specregs-const- VER)))))) +) + +; CGEN-FIXME: +; Unfortunately we can't iterate over the list of models due to the +; problem with referring to the parameters of a surrounding pmacro from +; within an enclosed .pmacro (perhaps related to "lexical scoping"). +; We get e.g. 'insn already defined:: (move-c-sprvn-p0)' with this: +;(.splice +; begin (.unsplice (.map (.pmacro (vn) (cris-move-c-spr vn (.pmacro (x) vn))) +; (cris-cpu-models))) +;) +(cris-move-c-spr v0 (.pmacro (x) v0)) +(cris-move-c-spr v3 (.pmacro (x) v3)) +(cris-move-c-spr v8 (.pmacro (x) v8)) +(cris-move-c-spr v10 (.pmacro (x) v10)) +(cris-move-c-spr v32 (.pmacro (x) v32)) + +; MOVE Ps,[Rd] [ Ps | 10100111 | Rd ] +; MOVE Ps,[Rd+] [ Ps | 11100111 | Rd ] +(.splice + begin + (.unsplice + (.map + (.pmacro + (VER) + (dni-cmwt-attr + (.sym move-spr-m VER) + "Move from special register to memory" + ((MACH (.sym cris VER))) + "move ${Ps},[${Rd-sfield}${inc}]" + (+ INFIX_MOVE_S_M SIZE_FIXED Rd-sfield Ps) + (sequence + ((SI rno)) + (set rno (regno Ps)) + (.splice + cond + (.unsplice + (.map + (.pmacro + (r) + ((eq rno (.cadr2 r)) + (cris-set-mem (.car2 r) Rd-sfield Ps))) + ((.sym cris-implemented-readable-specregs- VER)))) + (else (error "write from unimplemented special register"))) + (reset-x-p)))) + (cris-cpu-models))) +) + +; SBFS [Rs(+)] +; Instruction format: |0 0 1 1 1 m 1 1 0 1 1 1| Dest. | +(dni-cdt-attr + sbfs + "sbfs" + ((MACH crisv10)) + "sbfs [${Rd-sfield}${inc}]" + (+ (f-dest 3) INFIX_SBFS SIZE_FIXED MODEMEMP_YES inc Rd-sfield) + (error "SBFS isn't implemented") +) + +; MOVE Ss,Rd [ Ss | 11110111 | Rd ] +(dni-cdt-attr + move-ss-r + "move from support register to general register" + (MACH-V32) + "move ${Ss},${Rd-sfield}" + (+ Ss INFIX_MOVE_SS SIZE_FIXED (f-mode 3) Rd-sfield) + (sequence + () + (set Rd-sfield Ss) + (reset-x-p)) +) + +; MOVE Rs,Sd [ Sd | 10110111 | Rs ] +(dni-cdt-attr + move-r-ss + "move from general register to support register" + (MACH-V32) + "move ${Rs},${Sd}" + (+ Sd INFIX_MOVE_SS SIZE_FIXED (f-mode 2) Rs) + (sequence + () + (set Sd Rs) + (reset-x-p)) +) + +; MOVEM Rs,[Rd] [ Rs | 10111111 | Rd ] +; MOVEM Rs,[Rd+] [ Rs | 11111111 | Rd ] + +(define-pmacro (movem-to-mem-step regn) + ; Without the SI attribute, UINT is generated, which isn't supported by + ; the sim framework. + (if (ge SI (regno Rs-dfield) regn) + (sequence + ((SI tmp)) + (set tmp (reg h-gr regn)) + (set (mem SI addr) tmp) + (set addr (add addr 4)))) +) + +(dni + movem-r-m + "movem to memory" + (MACH-PRE-V32) + "movem ${Rs-dfield},[${Rd-sfield}${inc}]" + (+ INFIX_MOVEM_R_M MODEMEMP_YES inc SIZE_FIXED Rs-dfield Rd-sfield) + (sequence + ((SI addr) (BI postinc)) + ; FIXME: A copy of what's in cris-get-mem. + + ; Cache the incrementness of the operand. + (set postinc inc) + + ; CGEN-FIXME: Kludge to work around a CGEN bug: it doesn't see that + ; Rs-dfield is used as an input, causing the timing model to be wrong. + (sequence ((SI dummy)) (set dummy Rs-dfield)) + + ; Get the address from somewhere. If the insn was prefixed, it's in + ; the prefix-register. + (set addr + (if SI (eq prefix-set 0) + Rd-sfield + prefixreg)) + + (.splice + sequence () + (.unsplice (.map movem-to-mem-step (.iota 16 15 -1)))) + + ; Update the source-register for post-increments. + (if (ne postinc 0) + (set Rd-sfield + (if SI (eq prefix-set 0) addr prefixreg))) + (reset-x-p)) + (simplecris-movem-timing) +) + +(dni + movem-r-m-v32 + "movem to memory" + (MACH-V32) + "movem ${Rs-dfield},[${Rd-sfield}${inc}]" + (+ INFIX_MOVEM_R_M MODEMEMP_YES inc SIZE_FIXED Rs-dfield Rd-sfield) + (sequence + ((SI addr) (BI postinc)) + ; FIXME: Mostly a copy of what's in cris-get-mem. + + ; Cache the incrementness of the operand. + (set postinc inc) + + ; CGEN-FIXME: See movem-r-m. + (sequence ((SI dummy)) (set dummy Rs-dfield)) + + (set addr Rd-sfield) + + (.splice + sequence () + (.unsplice (.map movem-to-mem-step (.iota 16)))) + + ; Update the source-register for post-increments. + (if (ne postinc 0) + (set Rd-sfield addr)) + (reset-x-p)) + ; Unit u-mem must be specified before the u-movem-* for memory address + ; register stall count to be right. + ((crisv32 (unit u-mem) (unit u-movem-rtom) (unit u-exec-movem) + (unit u-mem-w))) +) + +; MOVEM [Rs],Rd [ Rd | 10111011 | Rs ] +; MOVEM [Rs+],Rd [ Rd | 11111011 | Rs ] + +(define-pmacro + (movem-to-reg-step regn) + ; Without the SI attribute, UINT is generated, which isn't supported by + ; the sim framework. + (if (ge SI (regno Rd) regn) + (sequence + ((SI tmp)) + (set tmp (mem SI addr)) + (set (reg h-gr regn) tmp) + (set addr (add addr 4)))) +) + +(dni + movem-m-r + "movem to register" + (MACH-PRE-V32) + "movem [${Rs}${inc}],${Rd}" + (+ Rd INFIX_MOVEM_M_R MODEMEMP_YES inc SIZE_FIXED Rs) + (sequence + ((SI addr) (BI postinc)) + ; FIXME: Mostly a copy of what's in cris-get-mem. + + ; Cache the incrementness of the operand. + (set postinc inc) + + ; Get the address from somewhere. If the insn was prefixed, it's in + ; the prefix-register. + (set addr + (if SI (eq prefix-set 0) + Rs + prefixreg)) + + ; CGEN-FIXME: See movem-r-m. + (sequence ((SI dummy)) (set dummy Rd)) + + (.splice + sequence () + ; The first movem step is left out because it can't happen; it's for + ; PC destination. See the pattern below. + (.unsplice (.map movem-to-reg-step (.iota 15 14 -1)))) + + ; Update the source-register for post-increments. + ; FIXME: No postinc-prefixed for v0 IIRC. + (if (ne postinc 0) + (set Rs (if SI (eq prefix-set 0) addr prefixreg))) + (reset-x-p)) + (simplecris-movem-timing) +) + +; (MOVEM [Rs],PC [ 1111 | 10111011 | Rs ]) +; (MOVEM [Rs+],PC [ 1111 | 11111011 | Rs ]) +; We have to special-case it for PC destination; used in longjump. +; We shouldn't *have* to special-case it; the main reason is (FIXME:) +; misgeneration of the simulator when the PC case is folded into the +; generic PRE-V32 movem; possibly related to then being a COND-CTI rather +; than an UNCOND-CTI. +(dni-cmt-attr + movem-m-pc + "movem to register, ending with PC" + (MACH-PRE-V32) + "movem [${Rs}${inc}],${Rd}" + (+ (f-dest 15) INFIX_MOVEM_M_R SIZE_FIXED Rs) + (sequence + ((SI addr) (BI postinc)) + ; FIXME: Mostly a copy of what's in cris-get-mem. + + ; Cache the incrementness of the operand. + (set postinc inc) + + ; Get the address from somewhere. If the insn was prefixed, it's in + ; the prefix-register. + (set addr + (if SI (eq prefix-set 0) + Rs + prefixreg)) + + ; FIXME: Add kludge here too *and* a test-case. + + (.splice + sequence () + ; The first movem step is for PC destination, used in longjmp. + (set pc (mem SI addr)) + (set addr (add addr 4)) + (.unsplice + (.map + (.pmacro + (regn) + (sequence + ((SI tmp)) + (set tmp (mem SI addr)) + (set (reg h-gr regn) tmp) + (set addr (add addr 4)))) + (.iota 15 14 -1)))) + + ; Update the source-register for post-increments. + ; FIXME: No postinc-prefixed for v0. + (if (ne postinc 0) + (set Rs (if SI (eq prefix-set 0) addr prefixreg))) + (reset-x-p)) +) + +(dni + movem-m-r-v32 + "movem to register" + (MACH-V32) + "movem [${Rs}${inc}],${Rd}" + (+ INFIX_MOVEM_M_R MODEMEMP_YES inc SIZE_FIXED Rs Rd) + (sequence + ((SI addr) (BI postinc)) + ; FIXME: A copy of what's in cris-get-mem + + ; Cache the incrementness of the operand. + (set postinc inc) + + ; Get the address from somewhere. + (set addr Rs) + + ; CGEN-FIXME: See movem-r-m. + (sequence ((SI dummy)) (set dummy Rd)) + + (.splice + sequence () + (.unsplice (.map movem-to-reg-step (.iota 16)))) + + ; Update the source-register for post-increments. + ; FIXME: No postinc-prefixed for v0 IIRC. + (if (ne postinc 0) + (set Rs addr)) + (reset-x-p)) + ; u-mem must be specified before the u-movem-* for memory source + ; register stall count to be right. + ((crisv32 (unit u-mem) (unit u-mem-r) (unit u-movem-mtor) + (unit u-exec-movem))) +) + +; ADD.m Rs,Rd [ Rd | 011000mm | Rs ] +(dni-cdt-bwd + add "add from register to register" + "$Rs,$Rd" + (+ Rd MODE_REGISTER R_ADD Rs) + (.pmacro (BWD) (cris-arit add BWD Rd Rs)) +) + +; ADD.m [Rs],Rd [ Rd | 101000mm | Rs ] +; ADD.m [Rs+],Rd [ Rd | 111000mm | Rs ] +(dni-cmt-bwd + add-m "add from memory to register" + "[${Rs}${inc}],${Rd}" + (+ INDIR_ADD Rs Rd) + (.pmacro (BWD) (cris-arit-3op add BWD Rd (cris-get-mem BWD Rs) Rs)) +) +; (ADD.m [PC+],Rd [ Rd | 111000mm | 1111 ]) +(dni-c-QI + addcbr "add constant byte to register" + "add.b ${sconst8}],${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_ADD SIZE_BYTE (f-source 15) sconst8) + (cris-arit add QI Rd sconst8) +) + +(dni-c-HI + addcwr "add constant word to register" + "add.w ${sconst16}],${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_ADD SIZE_WORD (f-source 15) sconst16) + (cris-arit add HI Rd sconst16) +) + +(dni-c-SI + addcdr "add constant dword to register" + "add.d ${const32}],${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_ADD SIZE_DWORD (f-source 15) const32) + (cris-arit add SI Rd const32) +) + +; (ADD.D [PC+],PC [ 1111 | 11100010 | 1111 ]) +; This insn is used for DSO-local jumps in PIC code. +(dni + addcpc "Relative jump by adding constant to PC" + (MACH-PC) + "add.d ${sconst32},PC" + (+ (f-dest 15) MODE_AUTOINCREMENT INDIR_ADD SIZE_DWORD (f-source 15) const32) + (sequence + ((SI newpc) (SI oldpc) (SI offs)) + (set offs const32) + (set oldpc (add SI pc 6)) + (set newpc (add SI oldpc offs)) + (set pc newpc) + (setf-arit SI add oldpc offs newpc cbit)) + (simplecris-common-timing ((unit u-const32) (unit u-stall) (unit u-exec))) +) + +; ADDS.z Rs,Rd [ Rd | 0100001z | Rs ] +(dni-cdt-sbw + adds "add sign-extended from register to register" + "$Rs,$Rd" + (+ Rd MODE_REGISTER R_ADDX Rs) + (.pmacro (BW) (cris-arit add SI Rd ((.sym BW -ext) (trunc BW Rs)))) +) + +; ADDS.z [Rs],Rd [ Rd | 1000001z | Rs ] +; ADDS.z [Rs+],Rd [ Rd | 1100001z | Rs ] +(dni-cmt-sbw + adds-m "add sign-extended from memory to register" + "[${Rs}${inc}],$Rd" + (+ Rd INDIR_ADDX Rs) + (.pmacro (BW) (cris-arit-3op add SI Rd ((.sym BW -ext) (cris-get-mem BW Rs)) Rs)) +) + +; (ADDS.z [PC+],Rd [ Rd | 1100001z | 1111 ]) +(dni-c-QI + addscbr "add sign-extended constant byte to register" + "[${Rs}${inc}],$Rd" + (+ Rd MODE_AUTOINCREMENT INDIR_ADDX SIGNED_BYTE (f-source 15) sconst8) + (cris-arit add SI Rd (ext SI (trunc QI sconst8))) +) +(dni-c-HI + addscwr "add sign-extended constant word to register" + "[${Rs}${inc}],$Rd" + (+ Rd MODE_AUTOINCREMENT INDIR_ADDX SIGNED_WORD (f-source 15) sconst16) + (cris-arit add SI Rd (ext SI (trunc HI sconst16))) +) + +; (ADDS.w [],PC [ 1111 | 10000011 | 1111 ]) +; For a PC destination, we support only the two-operand case +; (dest == src), which is used in switch/case statements. +; FIXME: Should implement ADD.D [PC],PC and ADDS.B [PC],PC for use if/when +; implementing CASE_VECTOR_SHORTEN_MODE. +(dni + addspcpc "add sign-extended prefixed arg to PC" + (MACH-PC) + "adds.w [PC],PC" + (+ (f-dest 15) MODE_INDIRECT INDIR_ADDX SIGNED_WORD (f-source 15)) + (sequence + ((SI newpc) (SI oldpc) (HI offs)) + (if (not prefix-set) + (error "Unexpected adds.w [PC],PC without prefix")) + ; We don't use cris-get-mem but instead special-case this one, since we + ; have most instruction fields fixed where cris-get-mem expects + ; field-parametrization by certain names. + (set offs (mem HI prefixreg)) + (set oldpc (add SI pc 2)) + (set newpc (add SI oldpc offs)) + (set pc newpc) + (setf-arit SI add oldpc (ext SI offs) newpc cbit)) + (simplecris-common-timing ((unit u-mem) (unit u-stall) (unit u-exec))) +) + +; ADDU.z Rs,Rd [ Rd | 0100000z | Rs ] +(dni-cdt-ubw + addu "add zero-extended from register to register" + "$Rs,$Rd" + (+ Rd MODE_REGISTER R_ADDX Rs) + (.pmacro (BW) (cris-arit add SI Rd ((.sym BW -zext) (trunc BW Rs)))) +) + +; ADDU.z [Rs],Rd [ Rd | 1000000z | Rs ] +; ADDU.z [Rs+],Rd [ Rd | 1100000z | Rs ] +(dni-cmt-ubw + addu-m "add zero-extended from memory to register" + "[${Rs}${inc}],$Rd" + (+ Rd INDIR_ADDX Rs) + (.pmacro (BW) + (cris-arit-3op add SI Rd ((.sym BW -zext) (cris-get-mem BW Rs)) Rs)) +) + +; (ADDU.z [PC+],Rd [ Rd | 1100000z | 1111 ]) +(dni-c-QI + adducbr "add zero-extended constant byte to register" + "[${Rs}${inc}],$Rd" + (+ Rd MODE_AUTOINCREMENT INDIR_ADDX UNSIGNED_BYTE (f-source 15) sconst8) + (cris-arit add SI Rd (zext SI (trunc QI sconst8))) +) +(dni-c-HI + adducwr "add zero-extended constant word to register" + "[${Rs}${inc}],$Rd" + (+ Rd MODE_AUTOINCREMENT INDIR_ADDX UNSIGNED_WORD (f-source 15) sconst16) + (cris-arit add SI Rd (zext SI (trunc HI sconst16))) +) + +; SUB.m Rs,Rd [ Rd | 011010mm | Rs ] +(dni-cdt-bwd + sub "subtract from register to register" + "$Rs,$Rd" + (+ Rd MODE_REGISTER R_SUB Rs) + (.pmacro (BWD) (cris-arit sub BWD Rd Rs)) +) + +; SUB.m [Rs],Rd [ Rd | 101010mm | Rs ] +; SUB.m [Rs+],Rd [ Rd | 111010mm | Rs ] +(dni-cmt-bwd + sub-m "subtract from memory to register" + "[${Rs}${inc}],${Rd}" + (+ INDIR_SUB Rs Rd) + (.pmacro (BWD) (cris-arit-3op sub BWD Rd (cris-get-mem BWD Rs) Rs)) +) + +; (SUB.m [PC+],Rd [ Rd | 111010mm | 1111 ] +(dni-c-QI + subcbr "subtract constant byte from register" + "sub.b ${sconst8}],${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_SUB SIZE_BYTE (f-source 15) sconst8) + (cris-arit sub QI Rd sconst8) +) + +(dni-c-HI + subcwr "subtract constant word from register" + "sub.w ${sconst16}],${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_SUB SIZE_WORD (f-source 15) sconst16) + (cris-arit sub HI Rd sconst16) +) + +(dni-c-SI + subcdr "subtract constant dword from register" + "sub.d ${const32}],${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_SUB SIZE_DWORD (f-source 15) const32) + (cris-arit sub SI Rd const32) +) + +; SUBS.z Rs,Rd [ Rd | 0100101z | Rs ] +(dni-cdt-sbw + subs "sub sign-extended from register to register" + "$Rs,$Rd" + (+ Rd MODE_REGISTER R_SUBX Rs) + (.pmacro (BW) (cris-arit sub SI Rd ((.sym BW -ext) (trunc BW Rs)))) +) + +; SUBS.z [Rs],Rd [ Rd | 1000101z | Rs ] +; SUBS.z [Rs+],Rd [ Rd | 1100101z | Rs ] +(dni-cmt-sbw + subs-m "sub sign-extended from memory to register" + "[${Rs}${inc}],$Rd" + (+ Rd INDIR_SUBX Rs) + (.pmacro (BW) + (cris-arit-3op sub SI Rd ((.sym BW -ext) (cris-get-mem BW Rs)) Rs)) +) + +; (SUBS.z [PC+],Rd [ Rd | 1100101z | 1111 ]) +(dni-c-QI + subscbr "sub sign-extended constant byte to register" + "[${Rs}${inc}],$Rd" + (+ Rd MODE_AUTOINCREMENT INDIR_SUBX SIGNED_BYTE (f-source 15) sconst8) + (cris-arit sub SI Rd (ext SI (trunc QI sconst8))) +) +(dni-c-HI + subscwr "sub sign-extended constant word to register" + "[${Rs}${inc}],$Rd" + (+ Rd MODE_AUTOINCREMENT INDIR_SUBX SIGNED_WORD (f-source 15) sconst16) + (cris-arit sub SI Rd (ext SI (trunc HI sconst16))) +) + +; SUBU.z Rs,Rd [ Rd | 0100100z | Rs ] +(dni-cdt-ubw + subu "sub zero-extended from register to register" + "$Rs,$Rd" + (+ Rd MODE_REGISTER R_SUBX Rs) + (.pmacro (BW) (cris-arit sub SI Rd ((.sym BW -zext) (trunc BW Rs)))) +) + +; SUBU.z [Rs],Rd [ Rd | 1000100z | Rs ] +; SUBU.z [Rs+],Rd [ Rd | 1100100z | Rs ] +(dni-cmt-ubw + subu-m "sub zero-extended from memory to register" + "[${Rs}${inc}],$Rd" + (+ Rd INDIR_SUBX Rs) + (.pmacro (BW) + (cris-arit-3op sub SI Rd ((.sym BW -zext) (cris-get-mem BW Rs)) Rs)) +) + +; (SUBU.z [PC+],Rd [ Rd | 1100100z | 1111 ]) +(dni-c-QI + subucbr "sub zero-extended constant byte to register" + "[${Rs}${inc}],$Rd" + (+ Rd MODE_AUTOINCREMENT INDIR_SUBX UNSIGNED_BYTE (f-source 15) sconst8) + (cris-arit sub SI Rd (zext SI (trunc QI sconst8))) +) +(dni-c-HI + subucwr "sub zero-extended constant word to register" + "[${Rs}${inc}],$Rd" + (+ Rd MODE_AUTOINCREMENT INDIR_SUBX UNSIGNED_WORD (f-source 15) sconst16) + (cris-arit sub SI Rd (zext SI (trunc HI sconst16))) +) + +; ADDC Rs,Rd [ Rd | 01010111 | Rs ] +(dni-cdt-attr + addc-r "addc from register to register" + (MACH-V32) + "addc $Rs,$Rd" + (+ Rd MODE_REGISTER RFIX_ADDC SIZE_FIXED Rs) + ; Since this is equivalent to "ax" plus "add.d Rs,Rd", we'll just do + ; that, semantically. + (sequence + () + (set-quiet xbit 1) + (cris-arit add SI Rd Rs)) +) + +; ADDC [Rs],Rd [ Rd | 10011010 | Rs ] +; ADDC [Rs+],Rd [ Rd | 11011010 | Rs ] +(dni-cmt-attr + addc-m "addc from memory to register" + (MACH-V32) + "addc [${Rs}${inc}],${Rd}" + (+ Rd INDIR_ADDC SIZE_DWORD Rs) + (sequence + () + (set-quiet xbit 1) + (cris-arit add SI Rd (cris-get-mem SI Rs))) +) + +; (ADDC [Rs+],Rd [ Rd | 11011010 | 1111 ]) +(dni-c-SI-attr + addc-c "addc constant to register" + (MACH-V32) + "addc ${const32},${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_ADDC SIZE_DWORD (f-source 15) const32) + (sequence + () + (set-quiet xbit 1) + (cris-arit add SI Rd const32)) +) + +; LAPC [PC+],Rd [ Rd | 11010111 1111 ] +(dni-c-SI-attr + lapc-d "lapc.d" + (MACH-V32) + "lapc.d ${const32-pcrel},${Rd}" + (+ Rd MODE_AUTOINCREMENT INFIX_LAPC SIZE_FIXED (f-source 15) const32-pcrel) + (sequence + () + (set Rd const32-pcrel) + (reset-x-p)) +) + +; LAPCQ qo,Rd [ Rd | 10010111 | qo ] +(dni-cdt-attr + lapcq "lapcq" + (MACH-V32) + "lapcq ${qo},${Rd}" + (+ Rd MODE_INDIRECT INFIX_LAPC SIZE_FIXED qo) + (sequence + () + (set Rd qo) + (reset-x-p)) +) + +; ADDI Rs.m,Rd [ Rs | 010100mm | Rd ] +(dni-cdt-bwd + addi "addi" + "${Rs-dfield}.m,${Rd-sfield}" + (+ Rd-sfield MODE_REGISTER R_ADDI Rs-dfield) + (.pmacro + (BWD) + (sequence + () + (set Rd-sfield (add SI Rd-sfield (mul Rs-dfield (.sym BWD -size)))) + (reset-x-p))) +) + +; NEG.m Rs,Rd [ Rd | 010110mm | Rs ] +(dni-cdt-bwd + neg "neg.m Rs,Rd" + "$Rs,$Rd" + (+ Rd MODE_REGISTER R_NEG Rs) + (.pmacro (BWD) (cris-arit3 sub BWD Rd 0 Rs)) +) + +; TEST.m [Rs] [ 0000101110mm | Rs ] +; TEST.m [Rs+] [ 0000111110mm | Rs ] +(dni-cmt-bwd + test-m "test.m [Rs(+)]" + "[${Rs}${inc}]" + (+ (f-dest 0) INDIR_TEST Rs) + (.pmacro + (BWD) + (sequence + ((BWD tmpd)) + (set tmpd (cris-get-mem BWD Rs)) + ; This is supposed to be the same result as for cmpq 0,X, hence same code. + (cris-arit6-int + sub BWD (.pmacro (sz regno val) (nop)) 0 tmpd 0 cbit cbit))) +) + +; MOVE.m Rs,[Rd] [ Rs | 101111mm | Rd ] +; MOVE.m Rs,[Rd+] [ Rs | 111111mm | Rd ] + +(dni-cmwt-bwd + move-r-m "move.m R,[]" + "${Rs-dfield},[${Rd-sfield}${inc}]" + (+ Rs-dfield INDIR_MOVE_R_M Rd-sfield) + (.pmacro + (BWD) + (sequence + ((BWD tmpd)) + (set tmpd Rs-dfield) + (cris-set-mem BWD Rd-sfield tmpd) + (reset-x-p))) +) + +; MULS.m Rs,Rd [ Rd | 110100mm | Rs ] +(dni-bwd-attr + muls "muls.m Rs,Rd" + ((MACH crisv10,crisv32)) + "$Rs,$Rd" + (+ Rd MODE_MULS INDIR_MUL Rs) + (.pmacro + (BWD) + (sequence + ((DI src1) (DI src2) (DI tmpr)) + (set src1 (ext DI (trunc BWD Rs))) + (set src2 (ext DI (trunc BWD Rd))) + (set tmpr (mul src1 src2)) + (set Rd (trunc SI tmpr)) + (set mof (trunc SI (srl tmpr 32))) + (setf-arit DI muls src1 src2 tmpr cbit))) + ((crisv10 (unit u-multiply) (unit u-exec)) + (crisv32 (unit u-multiply) (unit u-exec))) +) + +; MULU.m Rs,Rd [ Rd | 100100mm | Rs ] +(dni-bwd-attr + mulu "mulu.m Rs,Rd" + ((MACH crisv10,crisv32)) + "$Rs,$Rd" + (+ Rd MODE_MULU INDIR_MUL Rs) + (.pmacro + (BWD) + (sequence + ((DI src1) (DI src2) (DI tmpr)) + (set src1 (zext DI (trunc BWD Rs))) + (set src2 (zext DI (trunc BWD Rd))) + (set tmpr (mul src1 src2)) + (set Rd (trunc SI tmpr)) + (set mof (trunc SI (srl tmpr 32))) + (setf-arit DI mulu src1 src2 tmpr cbit))) + ((crisv10 (unit u-multiply) (unit u-exec)) + (crisv32 (unit u-multiply) (unit u-exec))) +) + +; MCP Ps,Rd [ Ps | 01111111 | Rd ] +(dni-cdt-attr + mcp "Multiply Carry Propagation" + (MACH-V32) + "mcp $Ps,$Rd" + (+ Ps MODE_REGISTER RFIX_MCP SIZE_FIXED Rd-sfield) + (sequence + () + (set-quiet xbit 1) + (set-quiet zbit 1) + (cris-arit5 add SI Rd-sfield Rd-sfield Ps rbit rbit)) +) + +; MSTEP Rs,Rd [ Rd | 01111111 | Rs ] +(dni-cdt-attr + mstep "Multiply step" + (MACH-PRE-V32) + "mstep $Rs,$Rd" + (+ Rd MODE_REGISTER RFIX_MSTEP SIZE_FIXED Rs) + (sequence + ((SI tmpd) (SI tmps)) + (set tmps Rs) + (set tmpd (add (sll Rd 1) (if SI nbit tmps 0))) + (set Rd tmpd) + (setf-move SI tmpd)) +) + +; DSTEP Rs,Rd [ Rd | 01101111 | Rs ] +(dni-cdt + dstep "Division step" + "dstep $Rs,$Rd" + (+ Rd MODE_REGISTER RFIX_DSTEP SIZE_FIXED Rs) + (sequence + ((SI tmp) (SI tmps) (SI tmpd)) + (set tmps Rs) + (set tmp (sll Rd 1)) + (set tmpd (if SI (geu tmp tmps) (sub tmp tmps) tmp)) + (set Rd tmpd) + (setf-move SI tmpd)) +) + +; ABS Rs,Rd [ Rd | 01101011 | Rs ] +(dni-cdt + abs "Absolut Instruction" + "abs $Rs,$Rd" + (+ Rd MODE_REGISTER RFIX_ABS SIZE_FIXED Rs) + (sequence + ((SI tmpd)) + (set tmpd (abs Rs)) + (set Rd tmpd) + (setf-move SI tmpd)) +) + +; AND.m Rs,Rd [ Rd | 011100mm | Rs ] +(dni-cdt-bwd + and "And from register to register" + "$Rs,$Rd" + (+ Rd MODE_REGISTER R_AND Rs) + (.pmacro + (BWD) + (sequence + ((BWD tmpd)) + (set tmpd (and BWD Rd Rs)) + (set-subreg-gr BWD (regno Rd) tmpd) + (setf-move BWD tmpd))) +) + +; AND.m [Rs],Rd [ Rd | 101100mm | Rs ] +; AND.m [Rs+],Rd [ Rd | 111100mm | Rs ] +(dni-cmt-bwd + and-m "And from memory to register" + "[${Rs}${inc}],${Rd}" + (+ INDIR_AND Rs Rd) + (.pmacro + (BWD) + (sequence + ((BWD tmpd)) + (set tmpd (and BWD Rd (cris-get-mem BWD Rs))) + (set-subreg-gr + BWD + (if SI (andif prefix-set (not inc)) (regno Rs) (regno Rd)) + tmpd) + (setf-move BWD tmpd))) +) + +; (AND.m [PC+],Rd [ Rd | 111100mm | 1111 ]) +(dni-c-QI + andcbr "And constant byte to register" + "and.b ${sconst8}],${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_AND SIZE_BYTE (f-source 15) sconst8) + (sequence + ((QI tmpd)) + (set tmpd (and QI Rd sconst8)) + (set-subreg-gr QI (regno Rd) tmpd) + (setf-move QI tmpd)) +) + +(dni-c-HI + andcwr "And constant word to register" + "and.w ${sconst16}],${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_AND SIZE_WORD (f-source 15) sconst16) + (sequence + ((HI tmpd)) + (set tmpd (and HI Rd sconst16)) + (set-subreg-gr HI (regno Rd) tmpd) + (setf-move HI tmpd)) +) + +(dni-c-SI + andcdr "And constant dword to register" + "and.d ${const32}],${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_AND SIZE_DWORD (f-source 15) const32) + (sequence + ((SI tmpd)) + (set tmpd (and SI Rd const32)) + (set-subreg-gr SI (regno Rd) tmpd) + (setf-move SI tmpd)) +) + +; ANDQ i,Rd [ Rd | 001100 | i ] +(dni-cdt + andq "And quick-immediate to register" + "andq $i,$Rd" + (+ Rd MODE_QUICK_IMMEDIATE Q_ANDQ i) + (sequence + ((SI tmpd)) + (set tmpd (and SI Rd i)) + (set-subreg-gr SI (regno Rd) tmpd) + (setf-move SI tmpd)) +) + +; OR.m Rs,Rd [ Rd | 011101mm | Rs ] +(dni-cdt-bwd + orr "Or from register to register" + "$Rs,$Rd" + (+ Rd MODE_REGISTER R_OR Rs) + (.pmacro + (BWD) + (sequence + ((BWD tmpd)) + (set tmpd (or BWD Rd Rs)) + (set-subreg-gr BWD (regno Rd) tmpd) + (setf-move BWD tmpd))) +) + +; OR.m [Rs],Rd [ Rd | 101101mm | Rs ] +; OR.m [Rs+],Rd [ Rd | 111101mm | Rs ] +(dni-cmt-bwd + or-m "Or from memory to register" + "[${Rs}${inc}],${Rd}" + (+ INDIR_OR Rs Rd) + (.pmacro + (BWD) + (sequence + ((BWD tmpd)) + (set tmpd (or BWD Rd (cris-get-mem BWD Rs))) + (set-subreg-gr + BWD + (if SI (andif prefix-set (not inc)) (regno Rs) (regno Rd)) + tmpd) + (setf-move BWD tmpd))) +) + +; (OR.m [PC+],Rd [ Rd | 111101mm | 1111 ]) +(dni-c-QI + orcbr "Or constant byte to register" + "or.b ${sconst8}],${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_OR SIZE_BYTE (f-source 15) sconst8) + (sequence + ((QI tmpd)) + (set tmpd (or QI Rd sconst8)) + (set-subreg-gr QI (regno Rd) tmpd) + (setf-move QI tmpd)) +) + +(dni-c-HI + orcwr "Or constant word to register" + "or.w ${sconst16}],${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_OR SIZE_WORD (f-source 15) sconst16) + (sequence + ((HI tmpd)) + (set tmpd (or HI Rd sconst16)) + (set-subreg-gr HI (regno Rd) tmpd) + (setf-move HI tmpd)) +) + +(dni-c-SI + orcdr "Or constant dword to register" + "or.d ${const32}],${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_OR SIZE_DWORD (f-source 15) const32) + (sequence + ((SI tmpd)) + (set tmpd (or SI Rd const32)) + (set-subreg-gr SI (regno Rd) tmpd) + (setf-move SI tmpd)) +) + +; ORQ i,Rd [ Rd | 001101 | i ] +(dni-cdt + orq "Or quick-immediate to register" + "orq $i,$Rd" + (+ Rd MODE_QUICK_IMMEDIATE Q_ORQ i) + (sequence + ((SI tmpd)) + (set tmpd (or SI Rd i)) + (set-subreg-gr SI (regno Rd) tmpd) + (setf-move SI tmpd)) +) + +; XOR Rs,Rd [ Rd | 01111011 | Rs ] +(dni-cdt + xor "Xor from register to register" + "xor $Rs,$Rd" + (+ Rd MODE_REGISTER RFIX_XOR SIZE_FIXED Rs) + (sequence + ((SI tmpd)) + (set tmpd (xor SI Rd Rs)) + (set Rd tmpd) + (setf-move SI tmpd)) +) + +(define-pmacro (swap-r x) + "Perform bit-wise swap within each byte" + (sequence + SI + ((SI tmpr)) + (set tmpr x) + (or (sll (and tmpr #x1010101) 7) + (or (sll (and tmpr #x2020202) 5) + (or (sll (and tmpr #x4040404) 3) + (or (sll (and tmpr #x8080808) 1) + (or (srl (and tmpr #x10101010) 1) + (or (srl (and tmpr #x20202020) 3) + (or (srl (and tmpr #x40404040) 5) + (srl (and tmpr #x80808080) 7))))))))) +) + +(define-pmacro (swap-b x) + "Perform byte-wise swap within each word" + (sequence + SI + ((SI tmpb)) + (set tmpb x) + (or (and (sll tmpb 8) #xff00ff00) + (and (srl tmpb 8) #xff00ff))) +) + +(define-pmacro (swap-w x) + "Perform word-wise swap within each dword" + (sequence + SI + ((SI tmpb)) + (set tmpb x) + (or (and (sll tmpb 16) #xffff0000) + (and (srl tmpb 16) #xffff))) +) + +(define-pmacro (swap-_ x) + "Do nothing swap-wise" + (error SI "SWAP without swap modifier isn't implemented") +) + +(define-pmacro (swap-n x) + "Perform bitwise not (that is, perform a not, not not perform)" + (inv x) +) + +(define-pmacro (swap-br x) "Combine swap-r and swap-b" (swap-r (swap-b x))) +(define-pmacro (swap-wr x) "Combine swap-r and swap-w" (swap-r (swap-w x))) +(define-pmacro (swap-wb x) "Combine swap-b and swap-w" (swap-b (swap-w x))) +(define-pmacro (swap-wbr x) "Combine swap-r and swap-wb" (swap-r (swap-wb x))) +(define-pmacro (swap-nr x) "Combine swap-r and swap-n" (swap-r (swap-n x))) +(define-pmacro (swap-nb x) "Combine swap-n and swap-b" (swap-b (swap-n x))) +(define-pmacro (swap-nbr x) "Combine swap-r and swap-nb" (swap-r (swap-nb x))) +(define-pmacro (swap-nw x) "Combine swap-n and swap-w" (swap-w (swap-n x))) +(define-pmacro (swap-nwr x) "Combine swap-r and swap-nw" (swap-r (swap-nw x))) +(define-pmacro (swap-nwb x) "Combine swap-b and swap-nw" (swap-b (swap-nw x))) +(define-pmacro (swap-nwbr x) "Combine swap-r and swap-nwb" (swap-r (swap-nwb x))) + +(define-pmacro (cris-swap swapcode val) + (sequence + SI + ((SI tmpcode) (SI tmpval) (SI tmpres)) + (set tmpcode swapcode) + (set tmpval val) + (.splice + cond + (.unsplice + (.map + (.pmacro + (x-swapcode x-swap) + ((eq tmpcode x-swapcode) + (set tmpres ((.sym swap- x-swap) tmpval)))) + (.iota 16) + (.splice _ (.unsplice cris-swap-codes))))) + tmpres) +) + +; NOT Rd alias for SWAPN Rd +(dni-cdt-attr + not "Not" + ((MACH crisv0,crisv3)) + "not ${Rs}" + (+ (f-dest 8) RFIX_SWAP MODE_REGISTER SIZE_FIXED Rd-sfield) + (sequence + ((SI tmp) (SI tmpd)) + (set tmp Rd-sfield) + (set tmpd (cris-swap 8 tmp)) + (set Rd-sfield tmpd) + (setf-move SI tmpd)) +) + +; SWAP<option> Rd [ N W B R | 01110111 | Rd ] +(dni-cdt-attr + swap "Swap" + ((MACH crisv8,crisv10,crisv32)) + "swap${swapoption} ${Rs}" + (+ swapoption RFIX_SWAP MODE_REGISTER SIZE_FIXED Rd-sfield) + (sequence + ((SI tmps) (SI tmpd)) + (set tmps Rd-sfield) + (set tmpd (cris-swap swapoption tmps)) + (set Rd-sfield tmpd) + (setf-move SI tmpd)) +) + +; ASR.m Rs,Rd [ Rd | 011110mm | Rs ] +(dni-cdt-bwd + asrr "Arithmetic shift right register count" + "$Rs,$Rd" + (+ Rd MODE_REGISTER R_ASR Rs) + (.pmacro + (BWD) + (sequence + ((BWD tmpd) (SI cnt1) (SI cnt2)) + (set cnt1 Rs) + (set cnt2 (if SI (ne (and cnt1 32) 0) 31 (and cnt1 31))) + (set tmpd (sra SI (ext SI (trunc BWD Rd)) cnt2)) + (set-subreg-gr BWD (regno Rd) tmpd) + (setf-move BWD tmpd))) +) + +; ASRQ c,Rd [ Rd | 0011101 | c ] +(dni-cdt + asrq "Arithmetic shift right quick-immediate count" + "asrq $c,${Rd}" + (+ Rd Q_ASHQ MODE_QUICK_IMMEDIATE (f-b5 1) c) + (sequence + ((SI tmpd)) + (set tmpd (sra Rd c)) + (set Rd tmpd) + (setf-move SI tmpd)) +) + +; LSR.m Rs,Rd [ Rd | 011111mm | Rs ] +(dni-cdt-bwd + lsrr "Logical shift right register count" + "$Rs,$Rd" + (+ Rd MODE_REGISTER R_LSR Rs) + (.pmacro + (BWD) + (sequence + ((SI tmpd) (SI cnt)) + (set cnt (and Rs 63)) + (set + tmpd + (if SI (ne (and cnt 32) 0) + 0 + (srl SI (zext SI (trunc BWD Rd)) (and cnt 31)))) + (set-subreg-gr BWD (regno Rd) tmpd) + (setf-move BWD tmpd))) +) + +; LSRQ c,Rd [ Rd | 0011111 | c ] +(dni-cdt + lsrq "Logical shift right quick-immediate count" + "lsrq $c,${Rd}" + (+ Rd Q_LSHQ MODE_QUICK_IMMEDIATE (f-b5 1) c) + (sequence + ((SI tmpd)) + (set tmpd (srl Rd c)) + (set Rd tmpd) + (setf-move SI tmpd)) +) + +; LSL.m Rs,Rd [ Rd | 010011mm | Rs ] +(dni-cdt-bwd + lslr "Logical shift left register count" + "$Rs,$Rd" + (+ Rd MODE_REGISTER R_LSL Rs) + (.pmacro + (BWD) + (sequence + ((SI tmpd) (SI cnt)) + (set cnt (and Rs 63)) + (set + tmpd + (if SI (ne (and cnt 32) 0) + 0 + (sll SI (zext SI (trunc BWD Rd)) (and cnt 31)))) + (set-subreg-gr BWD (regno Rd) tmpd) + (setf-move BWD tmpd))) +) + +; LSLQ c,Rd [ Rd | 0011110 | c ] +(dni-cdt + lslq "Logical shift left quick-immediate count" + "lslq $c,${Rd}" + (+ Rd Q_LSHQ MODE_QUICK_IMMEDIATE (f-b5 0) c) + (sequence + ((SI tmpd)) + (set tmpd (sll Rd c)) + (set Rd tmpd) + (setf-move SI tmpd)) +) + +; BTST Rs,Rd [ Rd | 01001111 | Rs ] +(dni-cdt + btst "Bit test register number" + "$Rs,$Rd" + (+ Rd MODE_REGISTER RFIX_BTST SIZE_FIXED Rs) + (sequence + ((SI tmpd) (SI cnt)) + (set tmpd (sll Rd (sub 31 (and Rs 31)))) + (setf-move SI tmpd)) +) + +; BTSTQ c,Rd [ Rd | 0011100 | c ] +(dni-cdt + btstq "Bit test quick-immediate number" + "btstq $c,${Rd}" + (+ Rd Q_ASHQ MODE_QUICK_IMMEDIATE (f-b5 0) c) + (sequence + ((SI tmpd)) + (set tmpd (sll Rd (sub 31 c))) + (setf-move SI tmpd)) +) + +; SETF <list of flags> [ P U I X | 01011011 | N Z V C ] +(dni-cdt + setf "Set condition code flags explicitly" + "setf ${list-of-flags}" + ; The zero-flags case gets flag operands wrong; there's a "_" + ; where there should have been nothing. Also, flags are in + ; assembly code allowed to be specified in any order, which + ; doesn't match the "flagbits" settings. Luckily we don't + ; use this field for assembly. + (+ RFIX_SETF MODE_REGISTER SIZE_FIXED list-of-flags) + (.splice + sequence + ((SI tmp)) + (set tmp list-of-flags) + (.unsplice + (.map + (.pmacro (ccbit) + (if (ne (and tmp (sll 1 (.sym ccbit -bitnumber))) 0) + (set (.sym ccbit bit) 1))) + cris-flagnames)) + (set prefix-set 0) + ; Unless x was specified to be set, set it to 0. + (if (eq (and tmp (sll 1 x-bitnumber)) 0) + (set xbit 0))) +) + +; CLEARF <list of flags> [ P U I X | 01011111 | N Z V C ] +(dni-cdt + clearf "Clear condition code flags explicitly" + "clearf ${list-of-flags}" + ; The zero-flags case gets flag operands wrong; there's a "_" + ; where there should have been nothing. Also, flags are in + ; assembly code allowed to be specified in any order, which + ; doesn't match the "flagbits" settings. Luckily we don't + ; use this field for assembly. + (+ RFIX_CLEARF MODE_REGISTER SIZE_FIXED list-of-flags) + (.splice + sequence + ((SI tmp)) + (set tmp list-of-flags) + (.unsplice + (.map + (.pmacro (ccbit) + (if (ne (and tmp (sll 1 (.sym ccbit -bitnumber))) 0) + (set (.sym ccbit bit) 0))) + cris-flagnames)) + (reset-x-p)) +) + +(define-pmacro + (rfe-rfn-guts) + "Common parts of RFE and RFN" + (sequence + ((USI oldccs) (USI samebits) (USI shiftbits) (USI keepmask) (BI p1)) + (set oldccs ccs) + ; Keeping U, S and I in user mode is handled by the CCS setter, so we + ; don't have to bother. Actually Q and M are handled too. The reason + ; to mask those out is to not have them shifted down into the second + ; flags level. + (set keepmask #xc0000000) + (set samebits (and oldccs keepmask)) + ; The P bit has its own equation. + (set shiftbits (and (srl (and oldccs #x3ffdfc00) 10) (inv keepmask))) + (set p1 (ne 0 (and oldccs #x20000))) + (set ccs (or (or samebits shiftbits) + (if SI (and rbit (not p1)) 0 #x80)))) +) + +; RFE [ 0010 10010011 0000 ] +(dni-cdt-attr + rfe + "RFE" + (MACH-V32) + "rfe" + (+ (f-dest 2) MODE_INDIRECT INFIX_RFE SIZE_FIXED (f-source 0)) + (rfe-rfn-guts) +) + +; SFE [ 0011 10010011 0000 ] +(dni-cdt-attr + sfe + "SFE" + (MACH-V32) + "sfe" + (+ (f-dest 3) MODE_INDIRECT INFIX_SFE SIZE_FIXED (f-source 0)) + (sequence + ((SI oldccs) (SI savemask)) + (set savemask #xc0000000) + (set oldccs ccs) + (set ccs + (or (and savemask oldccs) + (and (inv savemask) (sll oldccs 10))))) +) + +; RFG [ 0100 10010011 0000 ] +(dni-cdt-attr + rfg + "RFG" + (MACH-V32) + "rfg" + (+ (f-dest 4) MODE_INDIRECT INFIX_RFG SIZE_FIXED (f-source 0)) + (c-call VOID "@cpu@_rfg_handler" pc) +) + +; RFN [ 0101 10010011 0000 ] +(dni-cdt-attr + rfn + "RFN" + (MACH-V32) + "rfn" + (+ (f-dest 5) MODE_INDIRECT INFIX_RFN SIZE_FIXED (f-source 0)) + (sequence () (rfe-rfn-guts) (set mbit 1)) +) + +; HALT [ 1111 10010011 0000 ] +(dni-cdt-attr + halt + "HALT" + (MACH-V32) + "halt" + (+ (f-dest 15) MODE_INDIRECT INFIX_HALT SIZE_FIXED (f-source 0)) + (set pc (c-call USI "@cpu@_halt_handler" pc)) +) + +; Bcc o [ cc | 0000 | o ] +(dni + bcc-b "bcc byte operand" + () + "b${cc} ${o-pcrel}" + (+ cc QHI_BCC MODE_QUICK_IMMEDIATE o-pcrel) + (sequence + ((BI truthval)) + (set truthval (cris-condition cc)) + + ; Amazing as it may seem, there's no simpler way to find out + ; whether a branch is taken or not than to mark it through a kludge + ; like this. + (c-call VOID "@cpu@_branch_taken" pc o-pcrel truthval) + + (reset-x-p) + (if truthval + (delay 1 + (set pc o-pcrel)))) + (.splice (.unsplice (simplecris-timing)) + (crisv32 (unit u-branch) (unit u-exec))) +) +(dni + ba-b "ba byte operand" + () + "ba ${o-pcrel}" + (+ (f-dest 14) QHI_BCC MODE_QUICK_IMMEDIATE o-pcrel) + (sequence + () + (reset-x-p) + (delay 1 + (set pc o-pcrel))) + ((crisv32 (unit u-jump) (unit u-exec))) +) + +; Bcc [PC+] [ cc | 11011111 1111 ] +; (We don't implement the generic for pre-V32 but unused variant +; "Bcc [Rn(+)]" where n != 15.) +(dni + bcc-w "bcc, word operand" + () + "b${cc} ${o-word-pcrel}" + (+ cc MODE_AUTOINCREMENT INFIX_BCC_M SIZE_FIXED (f-source 15) o-word-pcrel) + (sequence + ((BI truthval)) + (set truthval (cris-condition cc)) + + ; Amazing as it may seem, there's no simpler way to find out + ; whether a branch is taken or not than to mark it through a kludge + ; like this. + (c-call VOID "@cpu@_branch_taken" pc o-word-pcrel truthval) + + (reset-x-p) + (if truthval + (delay 1 + (set pc o-word-pcrel)))) + (.splice + (.unsplice (simplecris-common-timing ((unit u-const16) (unit u-exec)))) + (crisv32 (unit u-const16) (unit u-branch) (unit u-exec))) +) +(dni + ba-w "ba word operand" + () + "ba ${o-word-pcrel}" + (+ (f-dest 14) MODE_AUTOINCREMENT INFIX_BCC_M SIZE_FIXED (f-source 15) o-word-pcrel) + (sequence + () + (reset-x-p) + (delay 1 + (set pc o-word-pcrel))) + (.splice + (.unsplice (simplecris-common-timing ((unit u-const16) (unit u-exec)))) + (crisv32 (unit u-const16) (unit u-jump) (unit u-exec))) +) + +; JAS Rs,Pd [ Pd | 10011011 | Rs ] +(dni + jas-r "JAS register" + (MACH-V32) + "jas ${Rs},${Pd}" + (+ Pd MODE_INDIRECT INFIX_JAS_R SIZE_FIXED Rs) + (sequence + () + (reset-x-p) + (if (andif (eq (regno Rs) 1) (eq (regno Pd) 11)) + ; We use this as a trigger; a normally reasonably rare instruction + ; used in the v32 trampoline. See comment at bdapqpc. + ; CGEN-FIXME: can't use (regno srp) [== (regno (reg h-sr 11))] + (c-call VOID "cris_flush_simulator_decode_cache" pc)) + (delay 1 + (sequence + () + (set Pd (add SI pc 4)) + (set pc Rs)))) + ((crisv32 (unit u-jump-r) (unit u-jump) (unit u-exec))) +) +; Same semantics in pre-V32, except no delay-slot. +; FIXME: Missing JIRC/JSRC/JBRC. +(dni-cdt-attr + jump-r "JUMP/JSR/JIR register" + (MACH-PC) + "jump/jsr/jir ${Rs}" + (+ Pd MODE_INDIRECT INFIX_JUMP_R SIZE_FIXED Rs) + (sequence + () + (set Pd (add SI pc 2)) + (set pc Rs) + (reset-x-p)) +) + +; JAS [PC+],Pd [ Pd | 11011011 1111 ] +(dni + jas-c "JAS constant" + (MACH-V32) + "jas ${const32},${Pd}" + (+ Pd MODE_AUTOINCREMENT INFIX_JAS_M SIZE_FIXED (f-source 15) const32) + (sequence + () + (reset-x-p) + (delay 1 + (sequence + () + (set Pd (add SI pc 8)) + (set pc const32)))) + ((crisv32 (unit u-const32) (unit u-jump) (unit u-exec))) +) + +; JUMP/JSR/JIR | Special r.| 1 m| 0 1 0 0| 1 1| Source | +(dni-cmt-attr + jump-m "JUMP/JSR/JIR memory" + (MACH-PC) + "jump/jsr/jir [${Rs}${inc}]" + (+ Pd INFIX_JUMP_M SIZE_FIXED Rs) + (sequence + () + (set Pd (add SI pc 2)) + (set pc (cris-get-mem SI Rs)) + (reset-x-p)) +) +(dni-c-SI-attr + jump-c "JUMP/JSR/JIR constant" + (MACH-PC) + "jump/jsr/jir ${const32}" + (+ Pd MODE_AUTOINCREMENT INFIX_JUMP_M SIZE_FIXED (f-source 15) const32) + (sequence + () + (set Pd (add SI pc 6)) + (set pc const32) + (reset-x-p)) +) + +; JUMP Ps [ Ps | 10011111 0000 ] +(dni + jump-p "JUMP special register" + (MACH-V32) + "jump ${Ps}" + (+ Ps MODE_INDIRECT INFIX_JUMP_P SIZE_FIXED (f-source 0)) + (sequence + () + (reset-x-p) + (delay 1 + (set pc Ps))) + ((crisv32 (unit u-jump-sr) + (unit u-exec))) +) + +; BAS [PC+],Pd [ Pd | 11101011 1111 ] +(dni + bas-c "BAS constant" + (MACH-V32) + "bas ${const32},${Pd}" + (+ Pd MODE_AUTOINCREMENT INFIX_BAS SIZE_FIXED (f-source 15) const32-pcrel) + (sequence + () + (reset-x-p) + (delay 1 + (sequence + () + (set Pd (add SI pc 8)) + (set pc const32-pcrel)))) + ((crisv32 (unit u-const32) (unit u-jump) (unit u-exec))) +) + +; JASC Rs,Pd [ Pd | 10110011 | Rs ] +(dni + jasc-r "JASC register" + (MACH-V32) + "jasc ${Rs},${Pd}" + (+ Pd MODE_INDIRECT INFIX_JASC SIZE_FIXED Rs) + (sequence + () + (reset-x-p) + (delay 1 + (sequence + () + (set Pd (add SI pc 8)) + (set pc Rs)))) + ((crisv32 (unit u-jump-r) (unit u-skip4) (unit u-jump) (unit u-exec))) +) + +; JASC [PC+],Pd [ Pd | 11110011 1111 ] +(dni + jasc-c "JASC constant" + (MACH-V32) + "jasc ${const32},${Pd}" + (+ Pd MODE_AUTOINCREMENT INFIX_JASC SIZE_FIXED (f-source 15) const32) + (sequence + () + (reset-x-p) + (delay 1 + (sequence + () + (set Pd (add SI pc 12)) + (set pc const32)))) + ((crisv32 (unit u-const32) (unit u-skip4) (unit u-jump) (unit u-exec))) +) + +; BASC [PC+],Pd [ Pd | 11101111 1111 ] +(dni + basc-c "BASC constant" + (MACH-V32) + "basc ${const32},${Pd}" + (+ Pd MODE_AUTOINCREMENT INFIX_BASC SIZE_FIXED (f-source 15) const32-pcrel) + (sequence + () + (reset-x-p) + (delay 1 + (sequence + () + (set Pd (add SI pc 12)) + (set pc const32-pcrel)))) + ((crisv32 (unit u-const32) (unit u-skip4) (unit u-jump) (unit u-exec))) +) + +; BREAK n [ 1110 | 10010011 | n ] + +(dni-cdt + break "break" + "break $n" + (+ (f-operand2 #xe) MODE_INDIRECT INFIX_BREAK SIZE_FIXED n) + (sequence () (reset-x-p) (set pc (c-call USI "@cpu@_break_handler" n pc))) +) + +; BOUND.m Rs,Rd [ Rd | 010111mm | Rs ] +(dni-cdt-bwd + bound-r "Bound register" + "${Rs},${Rd}" + (+ Rd R_BOUND MODE_REGISTER Rs) + (.pmacro + (BWD) + (sequence + ((SI tmpopd) (SI tmpops) (SI newval)) + (set tmpops ((.sym BWD -zext) (trunc BWD Rs))) + (set tmpopd Rd) + (set newval (if SI (ltu tmpops tmpopd) tmpops tmpopd)) + (set Rd newval) + (setf-move SI newval))) +) + +; BOUND.m [Rs],Rd [ Rd | 100111mm | Rs ] +; BOUND.m [Rs+],Rd [ Rd | 110111mm | Rs ] +(dni-cmt-bwd-attr + bound-m "Bound memory" + (MACH-PRE-V32) + "[${Rs}${inc}],${Rd}" + (+ Rd INDIR_BOUND Rs) + (.pmacro + (BWD) + (sequence + ((SI tmpopd) (SI tmpops) (SI newval)) + (set tmpops ((.sym BWD -zext) (cris-get-mem BWD Rs))) + (set tmpopd Rd) + (set newval (if SI (ltu tmpops tmpopd) tmpops tmpopd)) + (if (andif prefix-set (not inc)) + (set Rs newval) + (set Rd newval)) + (setf-move SI newval))) +) + +; (BOUND.m [PC+],Rd [ Rd | 110111mm | 1111 ]) +(dni-c-QI + bound-cb "Bound constant byte" + "bound.b [PC+],${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_BOUND SIZE_BYTE (f-source 15) uconst8) + (sequence + ((SI tmpopd) (SI tmpops) (SI newval)) + (set tmpops (zext SI (trunc QI uconst8))) + (set tmpopd Rd) + (set newval (if SI (ltu tmpops tmpopd) tmpops tmpopd)) + (set Rd newval) + (setf-move SI newval)) +) +(dni-c-HI + bound-cw "Bound constant word" + "bound.w [PC+],${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_BOUND SIZE_WORD (f-source 15) uconst16) + (sequence + ((SI tmpopd) (SI tmpops) (SI newval)) + (set tmpops (zext SI uconst16)) + (set tmpopd Rd) + (set newval (if SI (ltu tmpops tmpopd) tmpops tmpopd)) + (set Rd newval) + (setf-move SI newval)) +) +(dni-c-SI + bound-cd "Bound constant dword" + "bound.d [PC+],${Rd}" + (+ Rd MODE_AUTOINCREMENT INDIR_BOUND SIZE_DWORD (f-source 15) const32) + (sequence + ((SI tmpopd) (SI tmpops) (SI newval)) + (set tmpops const32) + (set tmpopd Rd) + (set newval (if SI (ltu tmpops tmpopd) tmpops tmpopd)) + (set Rd newval) + (setf-move SI newval)) +) + +; Scc Rd [ cc | 01010011 | Rd ] +(dni-cdt + scc "scc" + "s${cc} ${Rd-sfield}" + (+ cc MODE_REGISTER RFIX_SCC SIZE_FIXED Rd-sfield) + (sequence + ((BI truthval)) + (set truthval (cris-condition cc)) + (set Rd-sfield (zext SI truthval)) + (reset-x-p)) +) + +; LZ Rs,Rd [ Rd | 01110011 | Rs ] +(dni-cdt-attr + lz "lz" + (MACH-V3-UP) + "lz ${Rs},${Rd}" + (+ Rd MODE_REGISTER RFIX_LZ SIZE_FIXED Rs) + (sequence + ((SI tmpd) (SI tmp)) + (set tmp Rs) + (set tmpd 0) + (.splice + sequence + () + (.unsplice + (.map + (.pmacro (n) + (if (ge tmp 0) + (sequence + () + (set tmp (sll tmp 1)) + (set tmpd (add tmpd 1))))) + (.iota 32)))) + (set Rd tmpd) + (setf-move SI tmpd)) +) + +; ADDOQ o,Rs,ACR [ Rs | 0001 | o ] +(dni-cdt + addoq "addoq" + "addoq $o,$Rs,ACR" + (+ Rs-dfield MODE_QUICK_IMMEDIATE QHI_ADDOQ o) + (sequence + () + (set prefixreg (add SI Rs-dfield o)) + (set prefix-set 1)) +) + +; (BDAPQ o,PC [ 1111 | 0001 | o ]) +; This [PC+I] prefix is used in trampolines. +(dni-cdt-attr + bdapqpc "bdapq pc operand" + (MACH-PC UNCOND-CTI) + "bdapq $o,PC" + (+ (f-dest 15) MODE_QUICK_IMMEDIATE QHI_BDAP o) + (sequence + () + (set prefixreg (add SI (add SI pc 2) o)) + (set prefix-set 1) + ; When this *rare* instruction is seen, we're may be about to write + ; into code to be executed soon, *probably* covering addresses decoded + ; and executed before. If the simulator does not implement snooping + ; and automatic decoder flush, it will execute old code. This call + ; is a kludge for such simulators, asking it to abandon such cached + ; information. Anyway, it is hopefully enough to make CGEN-sim not + ; hork on gcc trampolines. + ; We mark this insn as UNCOND-CTI so this insn will end a simulator + ; basic block (the atomic unit of translation). + (c-call VOID "cris_flush_simulator_decode_cache" pc)) +) + +; (BDAP.D [PC+],PC [ 1111 | 11010110 | 1111 ] +; This [PC+I] prefix is used for DSO-local jumps in PIC code, together with +; move-m-pcplus-p0: "move [pc=pc+N],p0" +(dni-c-SI-attr + bdap-32-pc "bdap.d [PC+],PC" + (MACH-PC) + "bdap ${sconst32},PC" + (+ (f-dest 15) MODE_AUTOINCREMENT INDIR_BDAP_M SIZE_DWORD (f-source 15) const32) + (sequence + ((SI newpc) (SI oldpc) (SI offs)) + (set offs const32) + (set oldpc (add SI pc 6)) + (set newpc (add SI oldpc offs)) + (set prefixreg newpc) + (set prefix-set 1)) +) + +; (MOVE [PC+],P0 [ 0000 | 11100011 | 1111 ]) +; This insn is used for DSO-local jumps in PIC code. See bdap-32-pc. +(dni ; Must not use dni-cmt-* because we force MODE_AUTOINCREMENT. + move-m-pcplus-p0 "move [PC+],P0" + (MACH-PC) + "move [PC+],P0" + (+ (f-dest 0) MODE_AUTOINCREMENT INFIX_MOVE_M_S SIZE_FIXED (f-source 15)) + (if prefix-set + (sequence + ((QI dummy)) + ; We model the memory read, but throw the result away, as the + ; destination register is read-only. We need to assign the result of + ; cris-get-mem though, as CGEN-FIXME: invalid C code will otherwise + ; be generated. + (set dummy (cris-get-mem QI pc)) + (reset-x-p)) + (error "move [PC+],P0 without prefix is not implemented")) + (cris-mem-timing) +) + +; This insn is used in Linux in the form "move [$sp=$sp+16],$p8"; it's +; similar to move-m-pcplus-p0 above. The same comments apply here. +(dni + move-m-spplus-p8 "move [SP+],P8" + (MACH-PC) + "move [SP+],P8" + (+ (f-dest 8) MODE_AUTOINCREMENT INFIX_MOVE_M_S SIZE_FIXED (f-source 14)) + (if prefix-set + (sequence + ((SI dummy)) + (set dummy (cris-get-mem SI sp)) + (reset-x-p)) + (error "move [SP+],P8 without prefix is not implemented")) + (cris-mem-timing) +) + +; ADDO.m [Rs],Rd,ACR [ Rd | 100101mm | Rs ] +; ADDO.m [Rs+],Rd,ACR [ Rd | 110101mm | Rs ] +(dni-cmt-bwd + addo-m "addo.m memory" + "[${Rs}${inc}],$Rd,ACR" + (+ Rd INDIR_ADDO Rs) + (.pmacro + (BWD) + (sequence + ((BWD tmps)) + (set tmps (cris-get-mem BWD Rs)) + (set prefixreg (add SI Rd ((.sym BWD -ext) tmps))) + (set prefix-set 1))) +) + +; (ADDO.m [PC+],Rd,ACR [ Rd | 110101mm | 1111 ] +(dni-c-QI + addo-cb "addo.b const" + "addo.b [PC+],$Rd,ACR" + (+ Rd MODE_AUTOINCREMENT INDIR_ADDO SIZE_BYTE (f-source 15) sconst8) + (sequence + () + (set prefixreg (add SI Rd (ext SI (trunc QI sconst8)))) + (set prefix-set 1)) +) +(dni-c-HI + addo-cw "addo.w const" + "addo.w [PC+],$Rd,ACR" + (+ Rd MODE_AUTOINCREMENT INDIR_ADDO SIZE_WORD (f-source 15) sconst16) + (sequence + () + (set prefixreg (add SI Rd (ext SI (trunc HI sconst16)))) + (set prefix-set 1)) +) +(dni-c-SI + addo-cd "addo.d const" + "addo.d [PC+],$Rd,ACR" + (+ Rd MODE_AUTOINCREMENT INDIR_ADDO SIZE_DWORD (f-source 15) const32) + (sequence + () + (set prefixreg (add SI Rd const32)) + (set prefix-set 1)) +) + +; DIP [] | 0 0 0 0| 1 m| 0 1 0 1| 1 1| Source | + +(dni-cmt-attr + dip-m "dip mem" + (MACH-PRE-V32) + "dip [${Rs}${inc}]" + (+ (f-dest 0) INFIX_DIP SIZE_FIXED Rs) + (sequence + ((SI tmps)) + (set tmps (cris-get-mem SI Rs)) + (set prefixreg tmps) + (set prefix-set 1)) +) + +; (DIP [] | 0 0 0 0| 1 m| 0 1 0 1| 1 1| Source | ) +(dni-c-SI-attr + dip-c "dip [PC+]" + (MACH-PC) + "dip [PC+]" + (+ (f-dest 0) MODE_AUTOINCREMENT INFIX_DIP SIZE_FIXED (f-source 15) const32) + (sequence + () + (set prefixreg const32) + (set prefix-set 1)) +) + +; ADDI Rs.m,Rd,ACR [ Rs | 010101mm | Rd ] +; a.k.a. biap +(dni-cdt-bwd + addi-acr "addi prefix" + "${Rs-dfield}.m,${Rd-sfield},ACR" + (+ Rd-sfield MODE_REGISTER R_ADDI_ACR Rs-dfield) + (.pmacro + (BWD) + (sequence + () + (set prefixreg (add SI Rd-sfield (mul Rs-dfield (.sym BWD -size)))) + (set prefix-set 1))) +) + +(dni-cdt-bwd-attr + biap-pc "biap.m ${Rs-dfield},PC" + (MACH-PC) + "${Rs-dfield}.m,PC" + (+ Rs-dfield MODE_REGISTER R_ADDI_ACR (f-source 15)) + (.pmacro + (BWD) + (sequence + () + (set prefixreg (add SI (add SI pc 4) (mul Rs-dfield (.sym BWD -size)))) + (set prefix-set 1))) +) + +; FIDXI [Rs] [ 0000 | 11010011 | Rs ] +(dni-cdt-attr + fidxi "fidxi [Rs]" + (MACH-V32) + "fidxi [$Rs]" + (+ (f-dest 0) MODE_AUTOINCREMENT INFIX_FIDXI SIZE_FIXED Rs) + (set pc (c-call USI "@cpu@_fidxi_handler" pc Rs)) +) + +; FTAGI [Rs] [ 0001 | 11010011 | Rs ] +(dni-cdt-attr + ftagi "ftagi [Rs]" + (MACH-V32) + "fidxi [$Rs]" + (+ (f-dest 1) MODE_AUTOINCREMENT INFIX_FTAGI SIZE_FIXED Rs) + (set pc (c-call USI "@cpu@_ftagi_handler" pc Rs)) +) + +; FIDXD [Rs] [ 0000 | 10101011 | Rs ] +(dni-cdt-attr + fidxd "fidxd [Rs]" + (MACH-V32) + "fidxd [$Rs]" + (+ (f-dest 0) MODE_INDIRECT INFIX_FIDXD SIZE_FIXED Rs) + (set pc (c-call USI "@cpu@_fidxd_handler" pc Rs)) +) + +; FTAGD [Rs] [ 0001 | 10101011 | Rs ] +(dni-cdt-attr + ftagd "ftagd [Rs]" + (MACH-V32) + "ftagd [$Rs]" + (+ (f-dest 1) MODE_INDIRECT INFIX_FTAGD SIZE_FIXED Rs) + (set pc (c-call USI "@cpu@_ftagd_handler" pc Rs)) +) diff --git a/cpu/frv.cpu b/cpu/frv.cpu new file mode 100644 index 00000000000..893592427dc --- /dev/null +++ b/cpu/frv.cpu @@ -0,0 +1,9799 @@ +; Fujitsu FRV opcode support, for GNU Binutils. -*- Scheme -*- +; +; Copyright 2000, 2001, 2003, 2004, 2007, 2009 Free Software Foundation, Inc. +; +; Contributed by Red Hat Inc; developed under contract from Fujitsu. +; +; 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 must appear first + +(define-arch + (name frv) ; name of cpu architecture + (comment "Fujitsu FRV") + (insn-lsb0? #t) + (machs frv fr550 fr500 fr450 fr400 tomcat simple) + (isas frv) +) + +(define-isa + (name frv) + (base-insn-bitsize 32) + ; Initial bitnumbers to decode insns by. + (decode-assist (24 23 22 21 20 19 18)) + (liw-insns 1) ; The frv fetches up to 1 insns at a time. + (parallel-insns 8) ; The frv executes up to 8 insns at a time. +) + +; Cpu family definitions. +; +(define-cpu + ; cpu names must be distinct from the architecture name and machine names. + ; The "b" suffix stands for "base" and is the convention. + ; The "f" suffix stands for "family" and is the convention. + (name frvbf) + (comment "Fujitsu FRV base family") + (endian big) + (word-bitsize 32) +) + +; Generic FR-V machine. Supports the entire architecture +(define-mach + (name frv) + (comment "Generic FRV cpu") + (cpu frvbf) +) +(define-model + (name frv) (comment "Generic FRV model") (attrs) + (mach frv) + + (pipeline all "" () ((fetch) (decode) (execute) (writeback))) + + ; `state' is a list of variables for recording model state + ; (state) + + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) +) + +; FR550 machine +(define-mach + (name fr550) + (comment "FR550 cpu") + (cpu frvbf) +) +(define-model + (name fr550) (comment "FR550 model") (attrs) + (mach fr550) + + (pipeline all "" () ((fetch) (decode) (execute) (writeback))) + + ; `state' is a list of variables for recording model state + (state + ; State items + ; These are all masks with each bit representing one register. + (prev-fr-load DI) ; Previous use of FR register was target of a load + (prev-fr-complex-1 DI) ; Previous use of FR register has variable latency + (prev-fr-complex-2 DI) ; Previous use of FR register has variable latency + (prev-ccr-complex DI) ; Previous use of CCR register has variable latency + (prev-acc-mmac DI) ; Previous use of ACC register was a MMAC category + (cur-fr-load DI) ; Current use of FR register was target of a load + (cur-fr-complex-1 DI) ; Current use of FR register has variable latency + (cur-fr-complex-2 DI) ; Current use of FR register has variable latency + (cur-ccr-complex SI) ; Current use of CCR register has variable latency + (cur-acc-mmac DI) ; Current use of ACC register was a MMAC category + ) + ; Basic unit for instructions with no latency penalties + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) + ; Basic integer insn unit + (unit u-integer "Integer Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1) (ICCi_1 INT -1)) ; outputs + () ; profile action (default) + ) + ; Integer multiplication unit + (unit u-imul "Integer Multiplication Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRdoublek INT -1) (ICCi_1 INT -1)) ; outputs + () ; profile action (default) + ) + ; Integer division unit + (unit u-idiv "Integer Division Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1) (ICCi_1 INT -1)) ; outputs + () ; profile action (default) + ) + ; Branch unit + (unit u-branch "Branch Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) + (ICCi_2 INT -1) (FCCi_2 INT -1)) ; inputs + ((pc)) ; outputs + () ; profile action (default) + ) + ; Trap unit + (unit u-trap "Trap Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) + (ICCi_2 INT -1) (FCCi_2 INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Condition code check unit + (unit u-check "Check Unit" () + 1 1 ; issue done + () ; state + ((ICCi_3 INT -1) (FCCi_3 INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Float Arithmetic unit + (unit u-float-arith "Float Arithmetic unit" () + 1 1 ; issue done + () ; state + ((FRi INT -1) (FRj INT -1) ; inputs + (FRdoublei INT -1) (FRdoublej INT -1)) ; inputs + ((FRk INT -1) (FRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; Float Dual Arithmetic unit + (unit u-float-dual-arith "Float Arithmetic unit" () + ; This unit has a 2 cycle penalty -- see table 14-14 in the fr550 LSI + 1 3 ; issue done + () ; state + ((FRi INT -1) (FRj INT -1) ; inputs + (FRdoublei INT -1) (FRdoublej INT -1)) ; inputs + ((FRk INT -1) (FRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; Float Div unit + (unit u-float-div "Float Div unit" () + 1 1 ; issue done + () ; state + ((FRi INT -1) (FRj INT -1)) ; inputs + ((FRk INT -1)) ; outputs + () ; profile action (default) + ) + ; Float Square Root unit + (unit u-float-sqrt "Float Square Root unit" () + 1 1 ; issue done + () ; state + ((FRj INT -1) (FRdoublej INT -1)) ; inputs + ((FRk INT -1) (FRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; Float Compare unit + (unit u-float-compare "Float Compare unit" () + 1 1 ; issue done + () ; state + ((FRi INT -1) (FRj INT -1) + (FRdoublei INT -1) (FRdoublej INT -1)) ; inputs + ((FCCi_2 INT -1)) ; outputs + () ; profile action (default) + ) + ; Dual Float Compare unit + (unit u-float-dual-compare "Float Dual Compare unit" () + ; This unit has a 2 cycle penalty -- see table 14-14 in the fr550 LSI + 1 3 ; issue done + () ; state + ((FRi INT -1) (FRj INT -1)) ; inputs + ((FCCi_2 INT -1)) ; outputs + () ; profile action (default) + ) + ; FR Move to GR unit + (unit u-fr2gr "FR Move to GR Unit" () + 1 1 ; issue done + () ; state + ((FRintk INT -1)) ; inputs + ((GRj INT -1)) ; outputs + () ; profile action (default) + ) + ; GR Move to FR unit + (unit u-gr2fr "GR Move to FR Unit" () + 1 1 ; issue done + () ; state + ((GRj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; SPR Move to GR unit + (unit u-spr2gr "SPR Move to GR Unit" () + 1 1 ; issue done + () ; state + ((spr INT -1)) ; inputs + ((GRj INT -1)) ; outputs + () ; profile action (default) + ) + ; GR Move to SPR unit + (unit u-gr2spr "GR Move to SPR Unit" () + 1 1 ; issue done + () ; state + ((GRj INT -1)) ; inputs + ((spr INT -1)) ; outputs + () ; profile action (default) + ) + ; GR set half unit + (unit u-set-hilo "GR Set Half" () + 1 1 ; issue done + () ; state + () ; inputs + ((GRkhi INT -1) (GRklo INT -1)) ; outputs + () ; profile action (default) + ) + ; GR load unit + (unit u-gr-load "GR Load Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1) (GRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; GR store unit + (unit u-gr-store "GR Store Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) (GRk INT -1) (GRdoublek INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; FR load unit + (unit u-fr-load "FR Load Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((FRintk INT -1) (FRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; FR store unit + (unit u-fr-store "FR Store Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) (FRintk INT -1) (FRdoublek INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Swap unit + (unit u-swap "Swap Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1)) ; outputs + () ; profile action (default) + ) + ; FR Move to FR unit + (unit u-fr2fr "FR Move to FR Unit" () + 1 1 ; issue done + () ; state + ((FRi INT -1)) ; inputs + ((FRk INT -1)) ; outputs + () ; profile action (default) + ) + ; Clrgr unit + (unit u-clrgr "Clrgr Unit" () + 1 1 ; issue done + () ; state + ((GRk INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Clrfr unit + (unit u-clrfr "Clrfr Unit" () + 1 1 ; issue done + () ; state + ((FRk INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Insn cache invalidate unit + (unit u-ici "Insn cache invalidate unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache invalidate unit + (unit u-dci "Data cache invalidate unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache flush unit + (unit u-dcf "Data cache flush unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Insn cache preload unit + (unit u-icpl "Insn cache preload unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache preload unit + (unit u-dcpl "Data cache preload unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Insn cache unlock unit + (unit u-icul "Insn cache unlock unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache unlock unit + (unit u-dcul "Data cache unlock unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; commit unit + (unit u-commit "Commit Unit" () + 1 1 ; issue done + () ; state + ((GRk INT -1) (FRk INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Float Conversion unit + (unit u-float-convert "Float Conversion unit" () + 1 1 ; issue done + () ; state + ((FRj INT -1) (FRintj INT -1) (FRdoublej INT -1)) ; inputs + ((FRk INT -1) (FRintk INT -1) (FRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; Media units + (unit u-media "Media unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-quad "Media-quad unit" () + 1 1 ; issue done + () ; state + ((FRintieven INT -1) (FRintjeven INT -1)) ; inputs + ((FRintkeven INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-dual-expand "Media Dual Expand unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1)) ; inputs + ((FRintkeven INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-3-dual "Media-3-dual unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-3-acc "Media unit for M-3 using ACC" () + 1 1 ; issue done + () ; state + ((FRintj INT -1) (ACC40Si INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-3-acc-dual "Media-3-acc-dual unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1)) ; inputs + ((FRintkeven INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-3-wtacc "Media-3-wtacc unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (ACC40Sk INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + (unit u-media-3-mclracc "Media-3-mclracc unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) + (unit u-media-set "Media set" () + 1 1 ; issue done + () ; state + () ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-4 "Media-4 unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((ACC40Sk INT -1) (ACC40Uk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-4-acc "Media-4-acc unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1)) ; inputs + ((ACC40Sk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-4-acc-dual "Media-4-acc-dual unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1)) ; inputs + ((ACC40Sk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-4-add-sub "Media-4-add-sub unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1)) ; inputs + ((ACC40Sk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-4-add-sub-dual "Media-4-add-sub-dual unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1)) ; inputs + ((ACC40Sk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-4-quad "Media-4-quad unit" () + 1 1 ; issue done + () ; state + ((FRintieven INT -1) (FRintjeven INT -1)) ; inputs + ((ACC40Sk INT -1) (ACC40Uk INT -1)) ; outputs + () ; profile action (default) + ) +) + +; FR500 machine. +(define-mach + (name fr500) + (comment "FR500 cpu") + (cpu frvbf) +) +(define-model + (name fr500) (comment "FR500 model") (attrs) + (mach fr500) + + (pipeline all "" () ((fetch) (decode) (execute) (writeback))) + + ; `state' is a list of variables for recording model state + (state + ; State items + ; These are all masks with each bit representing one register. + (prev-fpop DI) ; Previous use of FR register was floating point insn + (prev-media DI) ; Previous use of FR register was a media insn + (prev-cc-complex DI) ; Previous use of ICC register was not simple + (cur-fpop DI) ; Current use of FR register was floating point insn + (cur-media DI) ; Current use of FR register was a media insn + (cur-cc-complex DI) ; Current use of ICC register was not simple + ) + ; Basic unit for instructions with no latency penalties + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) + ; Basic integer insn unit + (unit u-integer "Integer Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1) (ICCi_1 INT -1)) ; outputs + () ; profile action (default) + ) + ; Integer multiplication unit + (unit u-imul "Integer Multiplication Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRdoublek INT -1) (ICCi_1 INT -1)) ; outputs + () ; profile action (default) + ) + ; Integer division unit + (unit u-idiv "Integer Division Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1) (ICCi_1 INT -1)) ; outputs + () ; profile action (default) + ) + ; Branch unit + (unit u-branch "Branch Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) + (ICCi_2 INT -1) (FCCi_2 INT -1)) ; inputs + ((pc)) ; outputs + () ; profile action (default) + ) + ; Trap unit + (unit u-trap "Trap Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) + (ICCi_2 INT -1) (FCCi_2 INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Condition code check unit + (unit u-check "Check Unit" () + 1 1 ; issue done + () ; state + ((ICCi_3 INT -1) (FCCi_3 INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Clrgr unit + (unit u-clrgr "Clrgr Unit" () + 1 1 ; issue done + () ; state + ((GRk INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Clrfr unit + (unit u-clrfr "Clrfr Unit" () + 1 1 ; issue done + () ; state + ((FRk INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; GR set half unit + (unit u-set-hilo "GR Set Half" () + 1 1 ; issue done + () ; state + () ; inputs + ((GRkhi INT -1) (GRklo INT -1)) ; outputs + () ; profile action (default) + ) + ; GR load unit -- TODO doesn't handle quad + (unit u-gr-load "GR Load Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1) (GRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; GR store unit -- TODO doesn't handle quad + (unit u-gr-store "GR Store Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) (GRk INT -1) (GRdoublek INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; GR recovering store unit -- TODO doesn't handle quad + (unit u-gr-r-store "GR Recovering Store Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) (GRk INT -1) (GRdoublek INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; FR load unit -- TODO doesn't handle quad + (unit u-fr-load "FR Load Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((FRintk INT -1) (FRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; FR store unit -- TODO doesn't handle quad + (unit u-fr-store "FR Store Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) (FRintk INT -1) (FRdoublek INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; FR recovering store unit -- TODO doesn't handle quad + (unit u-fr-r-store "FR Recovering Store Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) (FRintk INT -1) (FRdoublek INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Swap unit + (unit u-swap "Swap Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1)) ; outputs + () ; profile action (default) + ) + ; FR Move to FR unit + (unit u-fr2fr "FR Move to FR Unit" () + 1 1 ; issue done + () ; state + ((FRi INT -1)) ; inputs + ((FRk INT -1)) ; outputs + () ; profile action (default) + ) + ; FR Move to GR unit + (unit u-fr2gr "FR Move to GR Unit" () + 1 1 ; issue done + () ; state + ((FRintk INT -1)) ; inputs + ((GRj INT -1)) ; outputs + () ; profile action (default) + ) + ; SPR Move to GR unit + (unit u-spr2gr "SPR Move to GR Unit" () + 1 1 ; issue done + () ; state + ((spr INT -1)) ; inputs + ((GRj INT -1)) ; outputs + () ; profile action (default) + ) + ; GR Move to FR unit + (unit u-gr2fr "GR Move to FR Unit" () + 1 1 ; issue done + () ; state + ((GRj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; GR Move to SPR unit + (unit u-gr2spr "GR Move to SPR Unit" () + 1 1 ; issue done + () ; state + ((GRj INT -1)) ; inputs + ((spr INT -1)) ; outputs + () ; profile action (default) + ) + ; Float Arithmetic unit + (unit u-float-arith "Float Arithmetic unit" () + 1 1 ; issue done + () ; state + ((FRi INT -1) (FRj INT -1) ; inputs + (FRdoublei INT -1) (FRdoublej INT -1)) ; inputs + ((FRk INT -1) (FRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; Float Dual Arithmetic unit + (unit u-float-dual-arith "Float Arithmetic unit" () + 1 1 ; issue done + () ; state + ((FRi INT -1) (FRj INT -1) ; inputs + (FRdoublei INT -1) (FRdoublej INT -1)) ; inputs + ((FRk INT -1) (FRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; Float Div unit + (unit u-float-div "Float Div unit" () + 1 1 ; issue done + () ; state + ((FRi INT -1) (FRj INT -1)) ; inputs + ((FRk INT -1)) ; outputs + () ; profile action (default) + ) + ; Float Square Root unit + (unit u-float-sqrt "Float Square Root unit" () + 1 1 ; issue done + () ; state + ((FRj INT -1) (FRdoublej INT -1)) ; inputs + ((FRk INT -1) (FRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; Float Dual Square Root unit + (unit u-float-dual-sqrt "Float Dual Square Root unit" () + 1 1 ; issue done + () ; state + ((FRj INT -1)) ; inputs + ((FRk INT -1)) ; outputs + () ; profile action (default) + ) + ; Float Compare unit + (unit u-float-compare "Float Compare unit" () + 1 1 ; issue done + () ; state + ((FRi INT -1) (FRj INT -1) + (FRdoublei INT -1) (FRdoublej INT -1)) ; inputs + ((FCCi_2 INT -1)) ; outputs + () ; profile action (default) + ) + ; Dual Float Compare unit + (unit u-float-dual-compare "Float Dual Compare unit" () + 1 1 ; issue done + () ; state + ((FRi INT -1) (FRj INT -1)) ; inputs + ((FCCi_2 INT -1)) ; outputs + () ; profile action (default) + ) + ; Float Conversion unit + (unit u-float-convert "Float Conversion unit" () + 1 1 ; issue done + () ; state + ((FRj INT -1) (FRintj INT -1) (FRdoublej INT -1)) ; inputs + ((FRk INT -1) (FRintk INT -1) (FRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; Dual Float Conversion unit + (unit u-float-dual-convert "Float Dual Conversion unit" () + 1 1 ; issue done + () ; state + ((FRj INT -1) (FRintj INT -1)) ; inputs + ((FRk INT -1) (FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media unit + (unit u-media "Media unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1) (ACC40Si INT -1) (ACCGi INT -1)) ; inputs + ((FRintk INT -1) (ACC40Sk INT -1) (ACC40Uk INT -1) (ACCGk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media Quad Arithmetic unit + (unit u-media-quad-arith "Media Quad Arithmetic unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media Dual Multiplication unit + (unit u-media-dual-mul "Media Dual Multiplication unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((ACC40Sk INT -1) (ACC40Uk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media Quad Multiplication unit + (unit u-media-quad-mul "Media Quad Multiplication unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((ACC40Sk INT -1) (ACC40Uk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media Quad Complex unit + (unit u-media-quad-complex "Media Quad Complex unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((ACC40Sk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media Dual Expand unit + (unit u-media-dual-expand "Media Dual Expand unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media Dual Unpack unit + (unit u-media-dual-unpack "Media Dual Unpack unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media Dual byte to half unit + (unit u-media-dual-btoh "Media Byte to byte" () + 1 1 ; issue done + () ; state + ((FRintj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media Dual half to byte unit + (unit u-media-dual-htob "Media Half to byte" () + 1 1 ; issue done + () ; state + ((FRintj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media Dual byte to half unit extended + (unit u-media-dual-btohe "Media Byte to byte extended" () + 1 1 ; issue done + () ; state + ((FRintj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Barrier unit + (unit u-barrier "Barrier unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) + ; Memory Barrier unit + (unit u-membar "Memory Barrier unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) + ; Insn cache invalidate unit + (unit u-ici "Insn cache invalidate unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache invalidate unit + (unit u-dci "Data cache invalidate unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache flush unit + (unit u-dcf "Data cache flush unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Insn cache preload unit + (unit u-icpl "Insn cache preload unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache preload unit + (unit u-dcpl "Data cache preload unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Insn cache unlock unit + (unit u-icul "Insn cache unlock unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache unlock unit + (unit u-dcul "Data cache unlock unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; commit unit + (unit u-commit "Commit Unit" () + 1 1 ; issue done + () ; state + ((GRk INT -1) (FRk INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) +) + +; Tomcat machine. Early version of fr500 machine +(define-mach + (name tomcat) + (comment "Tomcat -- early version of fr500") + (cpu frvbf) +) +(define-model + (name tomcat) (comment "Tomcat model") (attrs) + (mach tomcat) + + (pipeline all "" () ((fetch) (decode) (execute) (writeback))) + + ; `state' is a list of variables for recording model state + ; (state) + + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) +) + +; FR400 machine +(define-mach + (name fr400) + (comment "FR400 cpu") + (cpu frvbf) +) +(define-model + (name fr400) (comment "FR400 model") (attrs) + (mach fr400) + (pipeline all "" () ((fetch) (decode) (execute) (writeback))) + ; `state' is a list of variables for recording model state + (state + ; State items + ; These are all masks with each bit representing one register. + (prev-fp-load DI) ; Previous use of FR register was floating point load + (prev-fr-p4 DI) ; Previous use of FR register was media unit 4 + (prev-fr-p6 DI) ; Previous use of FR register was media unit 6 + (prev-acc-p2 DI) ; Previous use of ACC register was media unit 2 + (prev-acc-p4 DI) ; Previous use of ACC register was media unit 4 + (cur-fp-load DI) ; Current use of FR register is floating point load + (cur-fr-p4 DI) ; Current use of FR register is media unit 4 + (cur-fr-p6 DI) ; Current use of FR register is media unit 6 + (cur-acc-p2 DI) ; Current use of ACC register is media unit 2 + (cur-acc-p4 DI) ; Current use of ACC register is media unit 4 + ) + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) + ; Basic integer insn unit + (unit u-integer "Integer Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1) (ICCi_1 INT -1)) ; outputs + () ; profile action (default) + ) + ; Integer multiplication unit + (unit u-imul "Integer Multiplication Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRdoublek INT -1) (ICCi_1 INT -1)) ; outputs + () ; profile action (default) + ) + ; Integer division unit + (unit u-idiv "Integer Division Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1) (ICCi_1 INT -1)) ; outputs + () ; profile action (default) + ) + ; Branch unit + (unit u-branch "Branch Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) + (ICCi_2 INT -1) (FCCi_2 INT -1)) ; inputs + ((pc)) ; outputs + () ; profile action (default) + ) + ; Trap unit + (unit u-trap "Trap Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) + (ICCi_2 INT -1) (FCCi_2 INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Condition code check unit + (unit u-check "Check Unit" () + 1 1 ; issue done + () ; state + ((ICCi_3 INT -1) (FCCi_3 INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; GR set half unit + (unit u-set-hilo "GR Set Half" () + 1 1 ; issue done + () ; state + () ; inputs + ((GRkhi INT -1) (GRklo INT -1)) ; outputs + () ; profile action (default) + ) + ; GR load unit -- TODO doesn't handle quad + (unit u-gr-load "GR Load Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1) (GRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; GR store unit -- TODO doesn't handle quad + (unit u-gr-store "GR Store Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) (GRk INT -1) (GRdoublek INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; FR load unit -- TODO doesn't handle quad + (unit u-fr-load "FR Load Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((FRintk INT -1) (FRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; FR store unit -- TODO doesn't handle quad + (unit u-fr-store "FR Store Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) (FRintk INT -1) (FRdoublek INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Swap unit + (unit u-swap "Swap Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1)) ; outputs + () ; profile action (default) + ) + ; FR Move to GR unit + (unit u-fr2gr "FR Move to GR Unit" () + 1 1 ; issue done + () ; state + ((FRintk INT -1)) ; inputs + ((GRj INT -1)) ; outputs + () ; profile action (default) + ) + ; SPR Move to GR unit + (unit u-spr2gr "SPR Move to GR Unit" () + 1 1 ; issue done + () ; state + ((spr INT -1)) ; inputs + ((GRj INT -1)) ; outputs + () ; profile action (default) + ) + ; GR Move to FR unit + (unit u-gr2fr "GR Move to FR Unit" () + 1 1 ; issue done + () ; state + ((GRj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; GR Move to SPR unit + (unit u-gr2spr "GR Move to SPR Unit" () + 1 1 ; issue done + () ; state + ((GRj INT -1)) ; inputs + ((spr INT -1)) ; outputs + () ; profile action (default) + ) + ; Media unit M1 -- see table 13-8 in the fr400 LSI + (unit u-media-1 "Media-1 unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-1-quad "Media-1-quad unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-hilo "Media-hilo unit -- a variation of the Media-1 unit" () + 1 1 ; issue done + () ; state + () ; inputs + ((FRkhi INT -1) (FRklo INT -1)) ; outputs + () ; profile action (default) + ) + ; Media unit M2 -- see table 13-8 in the fr400 LSI + (unit u-media-2 "Media-2 unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((ACC40Sk INT -1) (ACC40Uk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-2-quad "Media-2-quad unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((ACC40Sk INT -1) (ACC40Uk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-2-acc "Media-2-acc unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1)) ; inputs + ((ACC40Sk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-2-acc-dual "Media-2-acc-dual unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1)) ; inputs + ((ACC40Sk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-2-add-sub "Media-2-add-sub unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1)) ; inputs + ((ACC40Sk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-2-add-sub-dual "Media-2-add-sub-dual unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1)) ; inputs + ((ACC40Sk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media unit M3 -- see table 13-8 in the fr400 LSI + (unit u-media-3 "Media-3 unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-3-dual "Media-3-dual unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-3-quad "Media-3-quad unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media unit M4 -- see table 13-8 in the fr400 LSI + (unit u-media-4 "Media-4 unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1) (FRintj INT -1)) ; inputs + ((ACC40Sk INT -1) (FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-4-accg "Media-4-accg unit" () + 1 1 ; issue done + () ; state + ((ACCGi INT -1) (FRinti INT -1)) ; inputs + ((ACCGk INT -1) (FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-4-acc-dual "Media-4-acc-dual unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media unit M6 -- see table 13-8 in the fr400 LSI + (unit u-media-6 "Media-6 unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media unit M7 -- see table 13-8 in the fr400 LSI + (unit u-media-7 "Media-1 unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((FCCk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media Dual Expand unit + (unit u-media-dual-expand "Media Dual Expand unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media Dual half to byte unit + (unit u-media-dual-htob "Media Half to byte" () + 1 1 ; issue done + () ; state + ((FRintj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Barrier unit + (unit u-barrier "Barrier unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) + ; Memory Barrier unit + (unit u-membar "Memory Barrier unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) + ; Insn cache invalidate unit + (unit u-ici "Insn cache invalidate unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache invalidate unit + (unit u-dci "Data cache invalidate unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache flush unit + (unit u-dcf "Data cache flush unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Insn cache preload unit + (unit u-icpl "Insn cache preload unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache preload unit + (unit u-dcpl "Data cache preload unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Insn cache unlock unit + (unit u-icul "Insn cache unlock unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache unlock unit + (unit u-dcul "Data cache unlock unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) +) + +; FR450 machine +(define-mach + (name fr450) + (comment "FR450 cpu") + (cpu frvbf) +) +(define-model + (name fr450) (comment "FR450 model") (attrs) + (mach fr450) + (pipeline all "" () ((fetch) (decode) (execute) (writeback))) + ; `state' is a list of variables for recording model state + (state + ; State items + ; These are all masks with each bit representing one register. + (prev-fp-load DI) ; Previous use of FR register was floating point load + (prev-fr-p4 DI) ; Previous use of FR register was media unit 4 + (prev-fr-p6 DI) ; Previous use of FR register was media unit 6 + (prev-acc-p2 DI) ; Previous use of ACC register was media unit 2 + (prev-acc-p4 DI) ; Previous use of ACC register was media unit 4 + (cur-fp-load DI) ; Current use of FR register is floating point load + (cur-fr-p4 DI) ; Current use of FR register is media unit 4 + (cur-fr-p6 DI) ; Current use of FR register is media unit 6 + (cur-acc-p2 DI) ; Current use of ACC register is media unit 2 + (cur-acc-p4 DI) ; Current use of ACC register is media unit 4 + ) + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) + ; Basic integer insn unit + (unit u-integer "Integer Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1) (ICCi_1 INT -1)) ; outputs + () ; profile action (default) + ) + ; Integer multiplication unit + (unit u-imul "Integer Multiplication Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRdoublek INT -1) (ICCi_1 INT -1)) ; outputs + () ; profile action (default) + ) + ; Integer division unit + (unit u-idiv "Integer Division Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1) (ICCi_1 INT -1)) ; outputs + () ; profile action (default) + ) + ; Branch unit + (unit u-branch "Branch Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) + (ICCi_2 INT -1) (FCCi_2 INT -1)) ; inputs + ((pc)) ; outputs + () ; profile action (default) + ) + ; Trap unit + (unit u-trap "Trap Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) + (ICCi_2 INT -1) (FCCi_2 INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Condition code check unit + (unit u-check "Check Unit" () + 1 1 ; issue done + () ; state + ((ICCi_3 INT -1) (FCCi_3 INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; GR set half unit + (unit u-set-hilo "GR Set Half" () + 1 1 ; issue done + () ; state + () ; inputs + ((GRkhi INT -1) (GRklo INT -1)) ; outputs + () ; profile action (default) + ) + ; GR load unit -- TODO doesn't handle quad + (unit u-gr-load "GR Load Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1) (GRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; GR store unit -- TODO doesn't handle quad + (unit u-gr-store "GR Store Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) (GRk INT -1) (GRdoublek INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; FR load unit -- TODO doesn't handle quad + (unit u-fr-load "FR Load Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((FRintk INT -1) (FRdoublek INT -1)) ; outputs + () ; profile action (default) + ) + ; FR store unit -- TODO doesn't handle quad + (unit u-fr-store "FR Store Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1) (FRintk INT -1) (FRdoublek INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Swap unit + (unit u-swap "Swap Unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + ((GRk INT -1)) ; outputs + () ; profile action (default) + ) + ; FR Move to GR unit + (unit u-fr2gr "FR Move to GR Unit" () + 1 1 ; issue done + () ; state + ((FRintk INT -1)) ; inputs + ((GRj INT -1)) ; outputs + () ; profile action (default) + ) + ; SPR Move to GR unit + (unit u-spr2gr "SPR Move to GR Unit" () + 1 1 ; issue done + () ; state + ((spr INT -1)) ; inputs + ((GRj INT -1)) ; outputs + () ; profile action (default) + ) + ; GR Move to FR unit + (unit u-gr2fr "GR Move to FR Unit" () + 1 1 ; issue done + () ; state + ((GRj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; GR Move to SPR unit + (unit u-gr2spr "GR Move to SPR Unit" () + 1 1 ; issue done + () ; state + ((GRj INT -1)) ; inputs + ((spr INT -1)) ; outputs + () ; profile action (default) + ) + ; Media unit M1 -- see table 14-8 in the fr450 LSI + (unit u-media-1 "Media-1 unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-1-quad "Media-1-quad unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-hilo "Media-hilo unit -- a variation of the Media-1 unit" () + 1 1 ; issue done + () ; state + () ; inputs + ((FRkhi INT -1) (FRklo INT -1)) ; outputs + () ; profile action (default) + ) + ; Media unit M2 -- see table 14-8 in the fr450 LSI + (unit u-media-2 "Media-2 unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((ACC40Sk INT -1) (ACC40Uk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-2-quad "Media-2-quad unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((ACC40Sk INT -1) (ACC40Uk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-2-acc "Media-2-acc unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1)) ; inputs + ((ACC40Sk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-2-acc-dual "Media-2-acc-dual unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1)) ; inputs + ((ACC40Sk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-2-add-sub "Media-2-add-sub unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1)) ; inputs + ((ACC40Sk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-2-add-sub-dual "Media-2-add-sub-dual unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1)) ; inputs + ((ACC40Sk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media unit M3 -- see table 14-8 in the fr450 LSI + (unit u-media-3 "Media-3 unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-3-dual "Media-3-dual unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-3-quad "Media-3-quad unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media unit M4 -- see table 14-8 in the fr450 LSI + (unit u-media-4 "Media-4 unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1) (FRintj INT -1)) ; inputs + ((ACC40Sk INT -1) (FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-4-accg "Media-4-accg unit" () + 1 1 ; issue done + () ; state + ((ACCGi INT -1) (FRinti INT -1)) ; inputs + ((ACCGk INT -1) (FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-4-acc-dual "Media-4-acc-dual unit" () + 1 1 ; issue done + () ; state + ((ACC40Si INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-media-4-mclracca "Media-4 unit for MCLRACC with #A=1" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) + ; Media unit M6 -- see table 14-8 in the fr450 LSI + (unit u-media-6 "Media-6 unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media unit M7 -- see table 14-8 in the fr450 LSI + (unit u-media-7 "Media-1 unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1) (FRintj INT -1)) ; inputs + ((FCCk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media Dual Expand unit + (unit u-media-dual-expand "Media Dual Expand unit" () + 1 1 ; issue done + () ; state + ((FRinti INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Media Dual half to byte unit + (unit u-media-dual-htob "Media Half to byte" () + 1 1 ; issue done + () ; state + ((FRintj INT -1)) ; inputs + ((FRintk INT -1)) ; outputs + () ; profile action (default) + ) + ; Barrier unit + (unit u-barrier "Barrier unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) + ; Memory Barrier unit + (unit u-membar "Memory Barrier unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) + ; Insn cache invalidate unit + (unit u-ici "Insn cache invalidate unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache invalidate unit + (unit u-dci "Data cache invalidate unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache flush unit + (unit u-dcf "Data cache flush unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Insn cache preload unit + (unit u-icpl "Insn cache preload unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache preload unit + (unit u-dcpl "Data cache preload unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Insn cache unlock unit + (unit u-icul "Insn cache unlock unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + ; Data cache unlock unit + (unit u-dcul "Data cache unlock unit" () + 1 1 ; issue done + () ; state + ((GRi INT -1) (GRj INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) +) + +; Simple machine - single issue integer machine +(define-mach + (name simple) + (comment "Simple single issue integer cpu") + (cpu frvbf) +) +(define-model + (name simple) (comment "Simple model") (attrs) + (mach simple) + (pipeline all "" () ((fetch) (decode) (execute) (writeback))) + ; `state' is a list of variables for recording model state + (state) + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) +) + +; The instruction fetch/execute cycle. +; +; This is how to fetch and decode an instruction. +; Leave it out for now + +; (define-extract (const SI 0)) + +; This is how to execute a decoded instruction. +; Leave it out for now + +; (define-execute (const SI 0)) + +; An attribute to describe which unit an insn runs in. +(define-attr + (for insn) + (type enum) + (name UNIT) + (comment "parallel execution pipeline selection") + ; The order of declaration is significant. + ; See the *_unit_mapping tables in frv.opc + ; Keep variations on the same unit together. + ; Keep the '01' variant immediately after the '1' variant in each unit. + ; Keep the 'ALL' variations immediately after the last numbered variant in each unit. + (values NIL + I0 I1 I01 I2 I3 IALL + FM0 FM1 FM01 FM2 FM3 FMALL FMLOW + B0 B1 B01 + C + MULT-DIV ; multiply/division slotted differently on different machines + IACC ; iacc multiply slotted differently on different machines + LOAD ; loads slotted differently on different machines + STORE ; store slotted differently on different machines + SCAN ; scan, scani slotted differently on different machines + DCPL ; dcpl slotted differently on different machines + MDUALACC ; media dual acc slotted differently on different machines + MDCUTSSI ; mdcutssi insn slotted differently on different machines + MCLRACC-1; mclracc A==1 slotted differently on different machines + NUM_UNITS + ) +) +; Attributes to describe major categories of insns +(define-attr + (for insn) + (type enum) + (name FR400-MAJOR) + (comment "fr400 major insn categories") + ; The order of declaration is significant. Keep variations on the same major + ; together. + (values NONE + I-1 I-2 I-3 I-4 I-5 + B-1 B-2 B-3 B-4 B-5 B-6 + C-1 C-2 + M-1 M-2 + ) +) +(define-attr + (for insn) + (type enum) + (name FR450-MAJOR) + (comment "fr450 major insn categories") + ; The order of declaration is significant. Keep variations on the same major + ; together. + (values NONE + I-1 I-2 I-3 I-4 I-5 + B-1 B-2 B-3 B-4 B-5 B-6 + C-1 C-2 + M-1 M-2 M-3 M-4 M-5 M-6 + ) +) +(define-attr + (for insn) + (type enum) + (name FR500-MAJOR) + (comment "fr500 major insn categories") + ; The order of declaration is significant. Keep variations on the same major + ; together. + (values NONE + I-1 I-2 I-3 I-4 I-5 I-6 + B-1 B-2 B-3 B-4 B-5 B-6 + C-1 C-2 + F-1 F-2 F-3 F-4 F-5 F-6 F-7 F-8 + M-1 M-2 M-3 M-4 M-5 M-6 M-7 M-8 + ) +) +(define-attr + (for insn) + (type enum) + (name FR550-MAJOR) + (comment "fr550 major insn categories") + ; The order of declaration is significant. Keep variations on the same major + ; together. + (values NONE + I-1 I-2 I-3 I-4 I-5 I-6 I-7 I-8 + B-1 B-2 B-3 B-4 B-5 B-6 + C-1 C-2 + F-1 F-2 F-3 F-4 + M-1 M-2 M-3 M-4 M-5 + ) +) +; Privileged insn +(define-attr + (for insn) + (type boolean) + (name PRIVILEGED) + (comment "insn only allowed in supervisor mode") +) +; Non-Excepting insn +(define-attr + (for insn) + (type boolean) + (name NON-EXCEPTING) + (comment "non-excepting insn") +) +; Conditional insn +(define-attr + (for insn) + (type boolean) + (name CONDITIONAL) + (comment "conditional insn") +) +; insn accesses FR registers +(define-attr + (for insn) + (type boolean) + (name FR-ACCESS) + (comment "insn accesses FR registers") +) +; insn preserves MSR.OVF +(define-attr + (for insn) + (type boolean) + (name PRESERVE-OVF) + (comment "Preserve value of MSR.OVF") +) +; "Audio" instruction provided by the fr405 but not the original fr400 core. +(define-attr + (for insn) + (type boolean) + (name AUDIO) + (comment "Audio instruction added with FR405") +) +; null attribute -- used as a place holder for where an attribue is required. +(define-attr + (for insn) + (type boolean) + (name NA) + (comment "placeholder attribute") + (attrs META) ; do not define in any generated file for now +) + +; IDOC attribute for instruction documentation. + +(define-attr + (for insn) + (type enum) + (name IDOC) + (comment "insn kind for documentation") + (attrs META) + (values + (MEM - () "Memory") + (ALU - () "ALU") + (FPU - () "FPU") + (BR - () "Branch") + (PRIV - () "Priviledged") + (MISC - () "Miscellaneous") + ) +) + +; Instruction fields. +; +; Attributes: +; PCREL-ADDR: pc relative value (for reloc and disassembly purposes) +; ABS-ADDR: absolute address (for reloc and disassembly purposes?) +; RESERVED: bits are not used to decode insn, must be all 0 +(dnf f-pack "packing bit" () 31 1) +(dnf f-op "primary opcode" () 24 7) +(dnf f-ope1 "extended opcode" () 11 6) +(dnf f-ope2 "extended opcode" () 9 4) +(dnf f-ope3 "extended opcode" () 15 3) +(dnf f-ope4 "extended opcode" () 7 2) + +(dnf f-GRi "source register 1" () 17 6) +(dnf f-GRj "source register 2" () 5 6) +(dnf f-GRk "destination register" () 30 6) + +(dnf f-FRi "source register 1" () 17 6) +(dnf f-FRj "source register 2" () 5 6) +(dnf f-FRk "destination register" () 30 6) + +(dnf f-CPRi "source register 1" () 17 6) +(dnf f-CPRj "source register 2" () 5 6) +(dnf f-CPRk "destination register" () 30 6) + +(dnf f-ACCGi "source register" () 17 6) +(dnf f-ACCGk "destination register" () 30 6) + +(dnf f-ACC40Si "40 bit signed accumulator" () 17 6) +(dnf f-ACC40Ui "40 bit unsigned accumulator" () 17 6) +(dnf f-ACC40Sk "40 bit accumulator" () 30 6) +(dnf f-ACC40Uk "40 bit accumulator" () 30 6) + +(dnf f-CRi "source register" () 14 3) +(dnf f-CRj "source register" () 2 3) +(dnf f-CRk "destination register" () 27 3) +(dnf f-CCi "condition register" () 11 3) + +(df f-CRj_int "target cr for ck insns" () 26 2 UINT + ((value pc) (sub WI value 4)) + ((value pc) (add WI value 4)) +) +(dnf f-CRj_float "target cr for fck insns" () 26 2) + +(dnf f-ICCi_1 "condition register" () 11 2) +(dnf f-ICCi_2 "condition register" () 26 2) +(dnf f-ICCi_3 "condition register" () 1 2) +(dnf f-FCCi_1 "condition register" () 11 2) +(dnf f-FCCi_2 "condition register" () 26 2) +(dnf f-FCCi_3 "condition register" () 1 2) +(dnf f-FCCk "condition register" () 26 2) +(dnf f-eir "exception insn register" () 17 6) + +(df f-s10 "10 bit sign extended" () 9 10 INT #f #f) +(df f-s12 "12 bit sign extended" () 11 12 INT #f #f) +(df f-d12 "12 bit sign extended" () 11 12 INT #f #f) +(df f-u16 "16 bit unsigned" () 15 16 UINT #f #f) +(df f-s16 "16 bit sign extended" () 15 16 INT #f #f) +(df f-s6 "6 bit signed" () 5 6 INT #f #f) +(df f-s6_1 "6 bit signed" () 11 6 INT #f #f) +(df f-u6 "6 bit unsigned" () 5 6 UINT #f #f) +(df f-s5 "5 bit signed" () 4 5 INT #f #f) + +(df f-u12-h "upper 6 bits of u12" () 17 6 INT #f #f) +(df f-u12-l "lower 6 bits of u12" () 5 6 UINT #f #f) +(dnmf f-u12 "12 bit signed immediate" () INT + (f-u12-h f-u12-l) + (sequence () ; insert + (set (ifield f-u12-h) (sra SI (ifield f-u12) 6)) + (set (ifield f-u12-l) (and (ifield f-u12) #x3f)) + ) + (sequence () ; extract + (set (ifield f-u12) (or (sll (ifield f-u12-h) 6) + (ifield f-u12-l))) + ) +) + +(dnf f-int-cc "integer branch conditions" () 30 4) +(dnf f-flt-cc "floating branch conditions" () 30 4) +(df f-cond "conditional arithmetic" () 8 1 UINT #f #f) +(df f-ccond "lr branch condition" () 12 1 UINT #f #f) +(df f-hint "2 bit branch prediction hint" () 17 2 UINT #f #f) +(df f-LI "link indicator" () 25 1 UINT #f #f) +(df f-lock "cache lock indicator" () 25 1 UINT #f #f) +(df f-debug "debug mode indicator" () 25 1 UINT #f #f) +(df f-A "all accumulator bit" () 17 1 UINT #f #f) +(df f-ae "cache all entries indicator" () 25 1 UINT #f #f) + +(dnf f-spr-h "upper 6 bits of spr" () 30 6) +(dnf f-spr-l "lower 6 bits of spr" () 17 6) +(dnmf f-spr "special purpose register" () UINT + (f-spr-h f-spr-l) + (sequence () ; insert + (set (ifield f-spr-h) (srl (ifield f-spr) (const 6))) + (set (ifield f-spr-l) (and (ifield f-spr) (const #x3f))) + ) + (sequence () ; extract + (set (ifield f-spr) (or (sll (ifield f-spr-h) (const 6)) + (ifield f-spr-l))) + ) +) + +(df f-label16 "18 bit pc relative signed offset" (PCREL-ADDR) 15 16 INT + ((value pc) (sra WI (sub WI value pc) (const 2))) + ((value pc) (add WI (sll WI value (const 2)) pc)) +) + +(df f-labelH6 "upper 6 bits of label24" () 30 6 INT #f #f) +(dnf f-labelL18 "lower 18 bits of label24" () 17 18) +(dnmf f-label24 "26 bit signed offset" (PCREL-ADDR) INT + (f-labelH6 f-labelL18) + ; insert + (sequence () + (set (ifield f-labelH6) + (sra WI (sub (ifield f-label24) pc) (const 20))) + (set (ifield f-labelL18) + (and (srl (sub (ifield f-label24) pc) (const 2)) + (const #x3ffff))) + ) + ; extract + (sequence () + (set (ifield f-label24) + (add (sll (or (sll (ifield f-labelH6) (const 18)) + (ifield f-labelL18)) + (const 2)) + pc))) +) + +(dnf f-LRAE "Load Real Address E flag" () 5 1) +(dnf f-LRAD "Load Real Address D flag" () 4 1) +(dnf f-LRAS "Load Real Address S flag" () 3 1) + +(dnf f-TLBPRopx "TLB Probe operation number" () 28 3) +(dnf f-TLBPRL "TLB Probe L flag" () 25 1) + +(dnf f-ICCi_1-null "null field" (RESERVED) 11 2) +(dnf f-ICCi_2-null "null field" (RESERVED) 26 2) +(dnf f-ICCi_3-null "null field" (RESERVED) 1 2) +(dnf f-FCCi_1-null "null field" (RESERVED) 11 2) +(dnf f-FCCi_2-null "null field" (RESERVED) 26 2) +(dnf f-FCCi_3-null "null field" (RESERVED) 1 2) +(dnf f-rs-null "null field" (RESERVED) 17 6) +(dnf f-GRi-null "null field" (RESERVED) 17 6) +(dnf f-GRj-null "null field" (RESERVED) 5 6) +(dnf f-GRk-null "null field" (RESERVED) 30 6) +(dnf f-FRi-null "null field" (RESERVED) 17 6) +(dnf f-FRj-null "null field" (RESERVED) 5 6) +(dnf f-ACCj-null "null field" (RESERVED) 5 6) +(dnf f-rd-null "null field" (RESERVED) 30 6) +(dnf f-cond-null "null field" (RESERVED) 30 4) +(dnf f-ccond-null "null field" (RESERVED) 12 1) +(dnf f-s12-null "null field" (RESERVED) 11 12) +(dnf f-label16-null "null field" (RESERVED) 15 16) +(dnf f-misc-null-1 "null field" (RESERVED) 30 5) +(dnf f-misc-null-2 "null field" (RESERVED) 11 6) +(dnf f-misc-null-3 "null field" (RESERVED) 11 4) +(dnf f-misc-null-4 "null field" (RESERVED) 17 2) +(dnf f-misc-null-5 "null field" (RESERVED) 17 16) +(dnf f-misc-null-6 "null field" (RESERVED) 30 3) +(dnf f-misc-null-7 "null field" (RESERVED) 17 3) +(dnf f-misc-null-8 "null field" (RESERVED) 5 3) +(dnf f-misc-null-9 "null field" (RESERVED) 5 4) +(dnf f-misc-null-10 "null field" (RESERVED) 16 5) +(dnf f-misc-null-11 "null field" (RESERVED) 5 1) + +(dnf f-LRA-null "null field" (RESERVED) 2 3) +(dnf f-TLBPR-null "null field" (RESERVED) 30 2) + +(dnf f-LI-off "null field" (RESERVED) 25 1) +(dnf f-LI-on "null field" (RESERVED) 25 1) + +; Relocation annotations. +(dsh h-reloc-ann "relocation annotation" () (register BI)) +(dnf f-reloc-ann "relocation annotation" () 0 0) + +(define-pmacro (dann xname xcomment xmode xparse xprint) + (define-operand + (name xname) + (comment xcomment) + (type h-reloc-ann) + (index f-reloc-ann) + (mode xmode) + (handlers (parse xparse) (print xprint)) + ) + ) + + +; Enums. + +; insn-op: +; FIXME: should use die macro or some such +(define-normal-insn-enum insn-op "insn op enums" () OP_ f-op + ( + "00" "01" "02" "03" "04" "05" "06" "07" "08" "09" "0A" "0B" "0C" "0D" "0E" "0F" + "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "1A" "1B" "1C" "1D" "1E" "1F" + "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "2A" "2B" "2C" "2D" "2E" "2F" + "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "3A" "3B" "3C" "3D" "3E" "3F" + "40" "41" "42" "43" "44" "45" "46" "47" "48" "49" "4A" "4B" "4C" "4D" "4E" "4F" + "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" "5A" "5B" "5C" "5D" "5E" "5F" + "60" "61" "62" "63" "64" "65" "66" "67" "68" "69" "6A" "6B" "6C" "6D" "6E" "6F" + "70" "71" "72" "73" "74" "75" "76" "77" "78" "79" "7A" "7B" "7C" "7D" "7E" "7F" + ) +) + +(define-normal-insn-enum insn-ope1 "insn ope enums" () OPE1_ f-ope1 + ( + "00" "01" "02" "03" "04" "05" "06" "07" "08" "09" "0A" "0B" "0C" "0D" "0E" "0F" + "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "1A" "1B" "1C" "1D" "1E" "1F" + "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "2A" "2B" "2C" "2D" "2E" "2F" + "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "3A" "3B" "3C" "3D" "3E" "3F" + ) +) + +(define-normal-insn-enum insn-ope2 "insn ope enums" () OPE2_ f-ope2 + ( + "00" "01" "02" "03" "04" "05" "06" "07" "08" "09" "0A" "0B" "0C" "0D" "0E" "0F" + ) +) + +(define-normal-insn-enum insn-ope3 "insn ope enums" () OPE3_ f-ope3 + ( + "00" "01" "02" "03" "04" "05" "06" "07" + ) +) + +(define-normal-insn-enum insn-ope4 "insn ope enums" () OPE4_ f-ope4 + ( + "0" "1" "2" "3" + ) +) + +; int-cc: integer branch conditions +; FIXME: should use die macro or some such +(define-normal-insn-enum int-cc "integer branch cond enums" () ICC_ f-int-cc + ( + "nev" "c" "v" "lt" "eq" "ls" "n" "le" + "ra" "nc" "nv" "ge" "ne" "hi" "p" "gt" + ) +) + +; flt-cc: floating-point/media branch conditions +; FIXME: should use die macro or some such +(define-normal-insn-enum flt-cc "float branch cond enums" () FCC_ f-flt-cc + ("nev" "u" "gt" "ug" "lt" "ul" "lg" "ne" + "eq" "ue" "ge" "uge" "le" "ule" "o" "ra") +) + +; Hardware pieces. +; These entries list the elements of the raw hardware. +; They're also used to provide tables and other elements of the assembly +; language. +(dnh h-pc "program counter" (PC PROFILE) (pc) () () ()) + +; The PSR. The individual fields are referenced more than the entire +; register, so reference them directly. We can assemble the +; entire register contents when necessary. +; +(dsh h-psr_imple "PSR.IMPLE" () (register UQI)) +(dsh h-psr_ver "PSR.VER" () (register UQI)) +(dsh h-psr_ice "PSR.ICE bit" () (register BI)) +(dsh h-psr_nem "PSR.NEM bit" () (register BI)) +(dsh h-psr_cm "PSR.CM bit" () (register BI)) +(dsh h-psr_be "PSR.BE bit" () (register BI)) +(dsh h-psr_esr "PSR.ESR bit" () (register BI)) +(dsh h-psr_ef "PSR.EF bit" () (register BI)) +(dsh h-psr_em "PSR.EM bit" () (register BI)) +(dsh h-psr_pil "PSR.PIL " () (register UQI)) +(dsh h-psr_ps "PSR.PS bit" () (register BI)) +(dsh h-psr_et "PSR.ET bit" () (register BI)) + +; PSR.S requires special handling because the shadow registers (SR0-SR4) must +; be switched with GR4-GR7 when changing from user to supervisor mode or +; vice-versa. +(define-hardware + (name h-psr_s) + (comment "PSR.S bit") + (attrs) + (type register BI) + (get) + (set (newval) (c-call VOID "@cpu@_h_psr_s_set_handler" newval)) +) + +; The TBR. The individual bits are referenced more than the entire +; register, so reference them directly. We can assemble the +; entire register contents when necessary. +; +(dsh h-tbr_tba "TBR.TBA" () (register UWI)) +(dsh h-tbr_tt "TBR.TT" () (register UQI)) + +; The BPSR. The individual bits are referenced more than the entire +; register, so reference them directly. We can assemble the +; entire register contents when necessary. +; +(dsh h-bpsr_bs "PSR.S bit" () (register BI)) +(dsh h-bpsr_bet "PSR.ET bit" () (register BI)) + +; General registers +; +(define-keyword + (name gr-names) + (print-name h-gr) + (prefix "") + (values + (sp 1) (fp 2) + (gr0 0)(gr1 1)(gr2 2)(gr3 3)(gr4 4)(gr5 5)(gr6 6)(gr7 7) + (gr8 8)(gr9 9)(gr10 10)(gr11 11)(gr12 12)(gr13 13)(gr14 14)(gr15 15) + (gr16 16)(gr17 17)(gr18 18)(gr19 19)(gr20 20)(gr21 21)(gr22 22)(gr23 23) + (gr24 24)(gr25 25)(gr26 26)(gr27 27)(gr28 28)(gr29 29)(gr30 30)(gr31 31) + (gr32 32)(gr33 33)(gr34 34)(gr35 35)(gr36 36)(gr37 37)(gr38 38)(gr39 39) + (gr40 40)(gr41 41)(gr42 42)(gr43 43)(gr44 44)(gr45 45)(gr46 46)(gr47 47) + (gr48 48)(gr49 49)(gr50 50)(gr51 51)(gr52 52)(gr53 53)(gr54 54)(gr55 55) + (gr56 56)(gr57 57)(gr58 58)(gr59 59)(gr60 60)(gr61 61)(gr62 62)(gr63 63) + ) +) + +(define-hardware + (name h-gr) + (comment "general registers") + (attrs PROFILE) + (type register USI (64)) + (indices extern-keyword gr-names) + (get (index) (c-call WI "@cpu@_h_gr_get_handler" index)) + (set (index newval) (c-call VOID "@cpu@_h_gr_set_handler" index newval)) +) + +; General Registers as double words +; These registers are shadowed onto h-gr +(define-hardware + (name h-gr_double) + (comment "general registers as double words") + (attrs PROFILE VIRTUAL) + (type register DI (32)) + ; FIXME: Need constraint to prohibit odd numbers. + (indices extern-keyword gr-names) + (get (index) + (c-call DI "@cpu@_h_gr_double_get_handler" index)) + (set (index newval) + (c-call VOID "@cpu@_h_gr_double_set_handler" index newval)) +) + +; General Registers as high and low half words +; These registers are shadowed onto h-gr +(define-hardware + (name h-gr_hi) + (comment "general registers as high half word") + (attrs PROFILE VIRTUAL) + (type register UHI (64)) + (indices extern-keyword gr-names) + (get (index) (c-call UHI "@cpu@_h_gr_hi_get_handler" index)) + (set (index newval) (c-call VOID "@cpu@_h_gr_hi_set_handler" index newval)) +) +(define-hardware + (name h-gr_lo) + (comment "general registers as low half word") + (attrs PROFILE VIRTUAL) + (type register UHI (64)) + (indices extern-keyword gr-names) + (get (index) (c-call UHI "@cpu@_h_gr_lo_get_handler" index)) + (set (index newval) (c-call VOID "@cpu@_h_gr_lo_set_handler" index newval)) +) + +; Floating Point Registers +(define-keyword + (name fr-names) + (print-name h-fr) + (prefix "") + (values + (fr0 0)(fr1 1)(fr2 2)(fr3 3)(fr4 4)(fr5 5)(fr6 6)(fr7 7) + (fr8 8)(fr9 9)(fr10 10)(fr11 11)(fr12 12)(fr13 13)(fr14 14)(fr15 15) + (fr16 16)(fr17 17)(fr18 18)(fr19 19)(fr20 20)(fr21 21)(fr22 22)(fr23 23) + (fr24 24)(fr25 25)(fr26 26)(fr27 27)(fr28 28)(fr29 29)(fr30 30)(fr31 31) + (fr32 32)(fr33 33)(fr34 34)(fr35 35)(fr36 36)(fr37 37)(fr38 38)(fr39 39) + (fr40 40)(fr41 41)(fr42 42)(fr43 43)(fr44 44)(fr45 45)(fr46 46)(fr47 47) + (fr48 48)(fr49 49)(fr50 50)(fr51 51)(fr52 52)(fr53 53)(fr54 54)(fr55 55) + (fr56 56)(fr57 57)(fr58 58)(fr59 59)(fr60 60)(fr61 61)(fr62 62)(fr63 63) + ) +) + +(define-hardware + (name h-fr) + (comment "floating point registers") + (attrs PROFILE) + (type register SF (64)) + (indices extern-keyword fr-names) + (get (index) (c-call SF "@cpu@_h_fr_get_handler" index)) + (set (index newval) (c-call VOID "@cpu@_h_fr_set_handler" index newval)) +) + +; Floating Point Registers as double precision +; These registers are shadowed onto h-fr + +(define-hardware + (name h-fr_double) + (comment "floating point registers as double precision") + (attrs PROFILE VIRTUAL) + (type register DF (32)) + ; FIXME: Need constraint to prohibit odd numbers. + (indices extern-keyword fr-names) + (get (index) + (c-call DF "@cpu@_h_fr_double_get_handler" index)) + (set (index newval) + (c-call VOID "@cpu@_h_fr_double_set_handler" index newval)) +) + +; Floating Point Registers as integer words. +; These registers are shadowed onto h-fr + +(define-hardware + (name h-fr_int) + (comment "floating point registers as integers") + (attrs PROFILE VIRTUAL) + (type register USI (64)) + (indices extern-keyword fr-names) + (get (index) + (c-call USI "@cpu@_h_fr_int_get_handler" index)) + (set (index newval) + (c-call VOID "@cpu@_h_fr_int_set_handler" index newval)) +) + +; Floating Point Registers as high and low half words +; These registers are shadowed onto h-fr +(define-hardware + (name h-fr_hi) + (comment "floating point registers as unsigned high half word") + (attrs PROFILE VIRTUAL) + (type register UHI (64)) + (indices extern-keyword fr-names) + (get (regno) (srl (reg h-fr_int regno) 16)) + (set (regno newval) (set (reg h-fr_int regno) + (or (and (reg h-fr_int regno) #xffff) + (sll newval 16)))) +) +(define-hardware + (name h-fr_lo) + (comment "floating point registers as unsigned low half word") + (attrs PROFILE VIRTUAL) + (type register UHI (64)) + (indices extern-keyword fr-names) + (get (regno) (and (reg h-fr_int regno) #xffff)) + (set (regno newval) (set (reg h-fr_int regno) + (or (and (reg h-fr_int regno) #xffff0000) + (and newval #xffff)))) +) + +; Floating Point Registers as unsigned bytes +; These registers are shadowed onto h-fr +(define-hardware + (name h-fr_0) + (comment "floating point registers as unsigned byte 0") + (attrs PROFILE VIRTUAL) + (type register UHI (64)) + (indices extern-keyword fr-names) + (get (regno) (and (reg h-fr_int regno) #xff)) + (set (regno newval) + (sequence () + (if (gt USI newval #xff) + (set newval #xff)) + (set (reg h-fr_int regno) (or (and (reg h-fr_int regno) #xffffff00) + newval)))) +) +(define-hardware + (name h-fr_1) + (comment "floating point registers as unsigned byte 1") + (attrs PROFILE VIRTUAL) + (type register UHI (64)) + (indices extern-keyword fr-names) + (get (regno) (and (srl (reg h-fr_int regno) 8) #xff)) + (set (regno newval) + (sequence () + (if (gt USI newval #xff) + (set newval #xff)) + (set (reg h-fr_int regno) (or (and (reg h-fr_int regno) #xffff00ff) + (sll newval 8))))) +) +(define-hardware + (name h-fr_2) + (comment "floating point registers as unsigned byte 2") + (attrs PROFILE VIRTUAL) + (type register UHI (64)) + (indices extern-keyword fr-names) + (get (regno) (and (srl (reg h-fr_int regno) 16) #xff)) + (set (regno newval) + (sequence () + (if (gt USI newval #xff) + (set newval #xff)) + (set (reg h-fr_int regno) (or (and (reg h-fr_int regno) #xff00ffff) + (sll newval 16))))) +) +(define-hardware + (name h-fr_3) + (comment "floating point registers as unsigned byte 3") + (attrs PROFILE VIRTUAL) + (type register UHI (64)) + (indices extern-keyword fr-names) + (get (regno) (and (srl (reg h-fr_int regno) 24) #xff)) + (set (regno newval) + (sequence () + (if (gt USI newval #xff) + (set newval #xff)) + (set (reg h-fr_int regno) (or (and (reg h-fr_int regno) #x00ffffff) + (sll newval 24))))) +) +; Coprocessor Registers +; +(define-keyword + (name cpr-names) + (print-name h-cpr) + (prefix "") + (values +(cpr0 0)(cpr1 1)(cpr2 2)(cpr3 3)(cpr4 4)(cpr5 5)(cpr6 6)(cpr7 7) +(cpr8 8)(cpr9 9)(cpr10 10)(cpr11 11)(cpr12 12)(cpr13 13)(cpr14 14)(cpr15 15) +(cpr16 16)(cpr17 17)(cpr18 18)(cpr19 19)(cpr20 20)(cpr21 21)(cpr22 22)(cpr23 23) +(cpr24 24)(cpr25 25)(cpr26 26)(cpr27 27)(cpr28 28)(cpr29 29)(cpr30 30)(cpr31 31) +(cpr32 32)(cpr33 33)(cpr34 34)(cpr35 35)(cpr36 36)(cpr37 37)(cpr38 38)(cpr39 39) +(cpr40 40)(cpr41 41)(cpr42 42)(cpr43 43)(cpr44 44)(cpr45 45)(cpr46 46)(cpr47 47) +(cpr48 48)(cpr49 49)(cpr50 50)(cpr51 51)(cpr52 52)(cpr53 53)(cpr54 54)(cpr55 55) +(cpr56 56)(cpr57 57)(cpr58 58)(cpr59 59)(cpr60 60)(cpr61 61)(cpr62 62)(cpr63 63) + ) +) + +(define-hardware + (name h-cpr) + (comment "coprocessor registers") + (attrs PROFILE (MACH frv)) + (type register WI (64)) + (indices extern-keyword cpr-names) +) + +; Coprocessor Registers as double words +; These registers are shadowed onto h-cpr +(define-hardware + (name h-cpr_double) + (comment "coprocessor registers as double words") + (attrs PROFILE VIRTUAL (MACH frv)) + (type register DI (32)) + ; FIXME: Need constraint to prohibit odd numbers. + (indices extern-keyword cpr-names) + (get (index) + (c-call DI "@cpu@_h_cpr_double_get_handler" index)) + (set (index newval) + (c-call VOID "@cpu@_h_cpr_double_set_handler" index newval)) +) + +; Special Purpose Registers +; +(define-keyword + (name spr-names) + (print-name h-spr) + (prefix "") + (values + (psr 0) (pcsr 1) (bpcsr 2) (tbr 3) (bpsr 4) + + (hsr0 16) (hsr1 17) (hsr2 18) (hsr3 19) + (hsr4 20) (hsr5 21) (hsr6 22) (hsr7 23) + (hsr8 24) (hsr9 25) (hsr10 26) (hsr11 27) + (hsr12 28) (hsr13 29) (hsr14 30) (hsr15 31) + (hsr16 32) (hsr17 33) (hsr18 34) (hsr19 35) + (hsr20 36) (hsr21 37) (hsr22 38) (hsr23 39) + (hsr24 40) (hsr25 41) (hsr26 42) (hsr27 43) + (hsr28 44) (hsr29 45) (hsr30 46) (hsr31 47) + (hsr32 48) (hsr33 49) (hsr34 50) (hsr35 51) + (hsr36 52) (hsr37 53) (hsr38 54) (hsr39 55) + (hsr40 56) (hsr41 57) (hsr42 58) (hsr43 59) + (hsr44 60) (hsr45 61) (hsr46 62) (hsr47 63) + (hsr48 64) (hsr49 65) (hsr50 66) (hsr51 67) + (hsr52 68) (hsr53 69) (hsr54 70) (hsr55 71) + (hsr56 72) (hsr57 73) (hsr58 74) (hsr59 75) + (hsr60 76) (hsr61 77) (hsr62 78) (hsr63 79) + + (ccr 256) (cccr 263) (lr 272) (lcr 273) (iacc0h 280) (iacc0l 281) (isr 288) + + (neear0 352) (neear1 353) (neear2 354) (neear3 355) + (neear4 356) (neear5 357) (neear6 358) (neear7 359) + (neear8 360) (neear9 361) (neear10 362) (neear11 363) + (neear12 364) (neear13 365) (neear14 366) (neear15 367) + (neear16 368) (neear17 369) (neear18 370) (neear19 371) + (neear20 372) (neear21 373) (neear22 374) (neear23 375) + (neear24 376) (neear25 377) (neear26 378) (neear27 379) + (neear28 380) (neear29 381) (neear30 382) (neear31 383) + + (nesr0 384) (nesr1 385) (nesr2 386) (nesr3 387) + (nesr4 388) (nesr5 389) (nesr6 390) (nesr7 391) + (nesr8 392) (nesr9 393) (nesr10 394) (nesr11 395) + (nesr12 396) (nesr13 397) (nesr14 398) (nesr15 399) + (nesr16 400) (nesr17 401) (nesr18 402) (nesr19 403) + (nesr20 404) (nesr21 405) (nesr22 406) (nesr23 407) + (nesr24 408) (nesr25 409) (nesr26 410) (nesr27 411) + (nesr28 412) (nesr29 413) (nesr30 414) (nesr31 415) + + (necr 416) + + (gner0 432) (gner1 433) + + (fner0 434) (fner1 435) + + (epcr0 512) (epcr1 513) (epcr2 514) (epcr3 515) + (epcr4 516) (epcr5 517) (epcr6 518) (epcr7 519) + (epcr8 520) (epcr9 521) (epcr10 522) (epcr11 523) + (epcr12 524) (epcr13 525) (epcr14 526) (epcr15 527) + (epcr16 528) (epcr17 529) (epcr18 530) (epcr19 531) + (epcr20 532) (epcr21 533) (epcr22 534) (epcr23 535) + (epcr24 536) (epcr25 537) (epcr26 538) (epcr27 539) + (epcr28 540) (epcr29 541) (epcr30 542) (epcr31 543) + (epcr32 544) (epcr33 545) (epcr34 546) (epcr35 547) + (epcr36 548) (epcr37 549) (epcr38 550) (epcr39 551) + (epcr40 552) (epcr41 553) (epcr42 554) (epcr43 555) + (epcr44 556) (epcr45 557) (epcr46 558) (epcr47 559) + (epcr48 560) (epcr49 561) (epcr50 562) (epcr51 563) + (epcr52 564) (epcr53 565) (epcr54 566) (epcr55 567) + (epcr56 568) (epcr57 569) (epcr58 570) (epcr59 571) + (epcr60 572) (epcr61 573) (epcr62 574) (epcr63 575) + + (esr0 576) (esr1 577) (esr2 578) (esr3 579) + (esr4 580) (esr5 581) (esr6 582) (esr7 583) + (esr8 584) (esr9 585) (esr10 586) (esr11 587) + (esr12 588) (esr13 589) (esr14 590) (esr15 591) + (esr16 592) (esr17 593) (esr18 594) (esr19 595) + (esr20 596) (esr21 597) (esr22 598) (esr23 599) + (esr24 600) (esr25 601) (esr26 602) (esr27 603) + (esr28 604) (esr29 605) (esr30 606) (esr31 607) + (esr32 608) (esr33 609) (esr34 610) (esr35 611) + (esr36 612) (esr37 613) (esr38 614) (esr39 615) + (esr40 616) (esr41 617) (esr42 618) (esr43 619) + (esr44 620) (esr45 621) (esr46 622) (esr47 623) + (esr48 624) (esr49 625) (esr50 626) (esr51 627) + (esr52 628) (esr53 629) (esr54 630) (esr55 631) + (esr56 632) (esr57 633) (esr58 634) (esr59 635) + (esr60 636) (esr61 637) (esr62 638) (esr63 639) + + (eir0 640) (eir1 641) (eir2 642) (eir3 643) + (eir4 644) (eir5 645) (eir6 646) (eir7 647) + (eir8 648) (eir9 649) (eir10 650) (eir11 651) + (eir12 652) (eir13 653) (eir14 654) (eir15 655) + (eir16 656) (eir17 657) (eir18 658) (eir19 659) + (eir20 660) (eir21 661) (eir22 662) (eir23 663) + (eir24 664) (eir25 665) (eir26 666) (eir27 667) + (eir28 668) (eir29 669) (eir30 670) (eir31 671) + + (esfr0 672) (esfr1 673) + + (sr0 768) (sr1 769) (sr2 770) (sr3 771) + + (scr0 832) (scr1 833) (scr2 834) (scr3 835) + + (fsr0 1024) (fsr1 1025) (fsr2 1026) (fsr3 1027) + (fsr4 1028) (fsr5 1029) (fsr6 1030) (fsr7 1031) + (fsr8 1032) (fsr9 1033) (fsr10 1034) (fsr11 1035) + (fsr12 1036) (fsr13 1037) (fsr14 1038) (fsr15 1039) + (fsr16 1040) (fsr17 1041) (fsr18 1042) (fsr19 1043) + (fsr20 1044) (fsr21 1045) (fsr22 1046) (fsr23 1047) + (fsr24 1048) (fsr25 1049) (fsr26 1050) (fsr27 1051) + (fsr28 1052) (fsr29 1053) (fsr30 1054) (fsr31 1055) + (fsr32 1056) (fsr33 1057) (fsr34 1058) (fsr35 1059) + (fsr36 1060) (fsr37 1061) (fsr38 1062) (fsr39 1063) + (fsr40 1064) (fsr41 1065) (fsr42 1066) (fsr43 1067) + (fsr44 1068) (fsr45 1069) (fsr46 1070) (fsr47 1071) + (fsr48 1072) (fsr49 1073) (fsr50 1074) (fsr51 1075) + (fsr52 1076) (fsr53 1077) (fsr54 1078) (fsr55 1079) + (fsr56 1080) (fsr57 1081) (fsr58 1082) (fsr59 1083) + (fsr60 1084) (fsr61 1085) (fsr62 1086) (fsr63 1087) + + ; FQ0-FQ31 are 64 bit registers. + ; These names allow access to the upper 32 bits of the FQ registers. + (fqop0 1088) (fqop1 1090) (fqop2 1092) (fqop3 1094) + (fqop4 1096) (fqop5 1098) (fqop6 1100) (fqop7 1102) + (fqop8 1104) (fqop9 1106) (fqop10 1108) (fqop11 1110) + (fqop12 1112) (fqop13 1114) (fqop14 1116) (fqop15 1118) + (fqop16 1120) (fqop17 1122) (fqop18 1124) (fqop19 1126) + (fqop20 1128) (fqop21 1130) (fqop22 1132) (fqop23 1134) + (fqop24 1136) (fqop25 1138) (fqop26 1140) (fqop27 1142) + (fqop28 1144) (fqop29 1146) (fqop30 1148) (fqop31 1150) + ; These names allow access to the lower 32 bits of the FQ registers. + (fqst0 1089) (fqst1 1091) (fqst2 1093) (fqst3 1095) + (fqst4 1097) (fqst5 1099) (fqst6 1101) (fqst7 1103) + (fqst8 1105) (fqst9 1107) (fqst10 1109) (fqst11 1111) + (fqst12 1113) (fqst13 1115) (fqst14 1117) (fqst15 1119) + (fqst16 1121) (fqst17 1123) (fqst18 1125) (fqst19 1127) + (fqst20 1129) (fqst21 1131) (fqst22 1133) (fqst23 1135) + (fqst24 1137) (fqst25 1139) (fqst26 1141) (fqst27 1143) + (fqst28 1145) (fqst29 1147) (fqst30 1149) (fqst31 1151) + ; These also access the lower 32 bits of the FQ registers. + ; These are not accessible as spr registers (see LSI appendix - section 13.4) +; (fq0 1089) (fq1 1091) (fq2 1093) (fq3 1095) +; (fq4 1097) (fq5 1099) (fq6 1101) (fq7 1103) +; (fq8 1105) (fq9 1107) (fq10 1109) (fq11 1111) +; (fq12 1113) (fq13 1115) (fq14 1117) (fq15 1119) +; (fq16 1121) (fq17 1123) (fq18 1125) (fq19 1127) +; (fq20 1129) (fq21 1131) (fq22 1133) (fq23 1135) +; (fq24 1137) (fq25 1139) (fq26 1141) (fq27 1143) +; (fq28 1145) (fq29 1147) (fq30 1149) (fq31 1151) + + (mcilr0 1272) (mcilr1 1273) + + (msr0 1280) (msr1 1281) (msr2 1282) (msr3 1283) + (msr4 1284) (msr5 1285) (msr6 1286) (msr7 1287) + (msr8 1288) (msr9 1289) (msr10 1290) (msr11 1291) + (msr12 1292) (msr13 1293) (msr14 1294) (msr15 1295) + (msr16 1296) (msr17 1297) (msr18 1298) (msr19 1299) + (msr20 1300) (msr21 1301) (msr22 1302) (msr23 1303) + (msr24 1304) (msr25 1305) (msr26 1306) (msr27 1307) + (msr28 1308) (msr29 1309) (msr30 1310) (msr31 1311) + (msr32 1312) (msr33 1313) (msr34 1314) (msr35 1315) + (msr36 1316) (msr37 1317) (msr38 1318) (msr39 1319) + (msr40 1320) (msr41 1321) (msr42 1322) (msr43 1323) + (msr44 1324) (msr45 1325) (msr46 1326) (msr47 1327) + (msr48 1328) (msr49 1329) (msr50 1330) (msr51 1331) + (msr52 1332) (msr53 1333) (msr54 1334) (msr55 1335) + (msr56 1336) (msr57 1337) (msr58 1338) (msr59 1339) + (msr60 1340) (msr61 1341) (msr62 1342) (msr63 1343) + + ; MQ0-MQ31 are 64 bit registers. + ; These names allow access to the upper 32 bits of the MQ registers. + (mqop0 1344) (mqop1 1346) (mqop2 1348) (mqop3 1350) + (mqop4 1352) (mqop5 1354) (mqop6 1356) (mqop7 1358) + (mqop8 1360) (mqop9 1362) (mqop10 1364) (mqop11 1366) + (mqop12 1368) (mqop13 1370) (mqop14 1372) (mqop15 1374) + (mqop16 1376) (mqop17 1378) (mqop18 1380) (mqop19 1382) + (mqop20 1384) (mqop21 1386) (mqop22 1388) (mqop23 1390) + (mqop24 1392) (mqop25 1394) (mqop26 1396) (mqop27 1398) + (mqop28 1400) (mqop29 1402) (mqop30 1404) (mqop31 1406) + ; These names allow access to the lower 32 bits of the MQ registers. + (mqst0 1345) (mqst1 1347) (mqst2 1349) (mqst3 1351) + (mqst4 1353) (mqst5 1355) (mqst6 1357) (mqst7 1359) + (mqst8 1361) (mqst9 1363) (mqst10 1365) (mqst11 1367) + (mqst12 1369) (mqst13 1371) (mqst14 1373) (mqst15 1375) + (mqst16 1377) (mqst17 1379) (mqst18 1381) (mqst19 1383) + (mqst20 1385) (mqst21 1387) (mqst22 1389) (mqst23 1391) + (mqst24 1393) (mqst25 1395) (mqst26 1397) (mqst27 1399) + (mqst28 1401) (mqst29 1403) (mqst30 1405) (mqst31 1407) + ; These also access the lower 32 bits of the MQ registers. + ; These are not accessible as spr registers (see LSI appendix - section 13.4) +; (mq0 1345) (mq1 1347) (mq2 1349) (mq3 1351) +; (mq4 1353) (mq5 1355) (mq6 1357) (mq7 1359) +; (mq8 1361) (mq9 1363) (mq10 1365) (mq11 1367) +; (mq12 1369) (mq13 1371) (mq14 1373) (mq15 1375) +; (mq16 1377) (mq17 1379) (mq18 1381) (mq19 1383) +; (mq20 1385) (mq21 1387) (mq22 1389) (mq23 1391) +; (mq24 1393) (mq25 1395) (mq26 1397) (mq27 1399) +; (mq28 1401) (mq29 1403) (mq30 1405) (mq31 1407) + + ; These are not accessible as spr registers (see LSI appendix - section 13.4) +; (acc0 1408) (acc1 1409) (acc2 1410) (acc3 1411) +; (acc4 1412) (acc5 1413) (acc6 1414) (acc7 1415) +; (acc8 1416) (acc9 1417) (acc10 1418) (acc11 1419) +; (acc12 1420) (acc13 1421) (acc14 1422) (acc15 1423) +; (acc16 1424) (acc17 1425) (acc18 1426) (acc19 1427) +; (acc20 1428) (acc21 1429) (acc22 1430) (acc23 1431) +; (acc24 1432) (acc25 1433) (acc26 1434) (acc27 1435) +; (acc28 1436) (acc29 1437) (acc30 1438) (acc31 1439) +; (acc32 1440) (acc33 1441) (acc34 1442) (acc35 1443) +; (acc36 1444) (acc37 1445) (acc38 1446) (acc39 1447) +; (acc40 1448) (acc41 1449) (acc42 1450) (acc43 1451) +; (acc44 1452) (acc45 1453) (acc46 1454) (acc47 1455) +; (acc48 1456) (acc49 1457) (acc50 1458) (acc51 1459) +; (acc52 1460) (acc53 1461) (acc54 1462) (acc55 1463) +; (acc56 1464) (acc57 1465) (acc58 1466) (acc59 1467) +; (acc60 1468) (acc61 1469) (acc62 1470) (acc63 1471) + +; (accg0 1472) (accg1 1473) (accg2 1474) (accg3 1475) +; (accg4 1476) (accg5 1477) (accg6 1478) (accg7 1479) +; (accg8 1480) (accg9 1481) (accg10 1482) (accg11 1483) +; (accg12 1484) (accg13 1485) (accg14 1486) (accg15 1487) +; (accg16 1488) (accg17 1489) (accg18 1490) (accg19 1491) +; (accg20 1492) (accg21 1493) (accg22 1494) (accg23 1495) +; (accg24 1496) (accg25 1497) (accg26 1498) (accg27 1499) +; (accg28 1500) (accg29 1501) (accg30 1502) (accg31 1503) +; (accg32 1504) (accg33 1505) (accg34 1506) (accg35 1507) +; (accg36 1508) (accg37 1509) (accg38 1510) (accg39 1511) +; (accg40 1512) (accg41 1513) (accg42 1514) (accg43 1515) +; (accg44 1516) (accg45 1517) (accg46 1518) (accg47 1519) +; (accg48 1520) (accg49 1521) (accg50 1522) (accg51 1523) +; (accg52 1524) (accg53 1525) (accg54 1526) (accg55 1527) +; (accg56 1528) (accg57 1529) (accg58 1530) (accg59 1531) +; (accg60 1532) (accg61 1533) (accg62 1534) (accg63 1535) + + (ear0 1536) (ear1 1537) (ear2 1538) (ear3 1539) + (ear4 1540) (ear5 1541) (ear6 1542) (ear7 1543) + (ear8 1544) (ear9 1545) (ear10 1546) (ear11 1547) + (ear12 1548) (ear13 1549) (ear14 1550) (ear15 1551) + (ear16 1552) (ear17 1553) (ear18 1554) (ear19 1555) + (ear20 1556) (ear21 1557) (ear22 1558) (ear23 1559) + (ear24 1560) (ear25 1561) (ear26 1562) (ear27 1563) + (ear28 1564) (ear29 1565) (ear30 1566) (ear31 1567) + (ear32 1568) (ear33 1569) (ear34 1570) (ear35 1571) + (ear36 1572) (ear37 1573) (ear38 1574) (ear39 1575) + (ear40 1576) (ear41 1577) (ear42 1578) (ear43 1579) + (ear44 1580) (ear45 1581) (ear46 1582) (ear47 1583) + (ear48 1584) (ear49 1585) (ear50 1586) (ear51 1587) + (ear52 1588) (ear53 1589) (ear54 1590) (ear55 1591) + (ear56 1592) (ear57 1593) (ear58 1594) (ear59 1595) + (ear60 1596) (ear61 1597) (ear62 1598) (ear63 1599) + + (edr0 1600) (edr1 1601) (edr2 1602) (edr3 1603) + (edr4 1604) (edr5 1605) (edr6 1606) (edr7 1607) + (edr8 1608) (edr9 1609) (edr10 1610) (edr11 1611) + (edr12 1612) (edr13 1613) (edr14 1614) (edr15 1615) + (edr16 1616) (edr17 1617) (edr18 1618) (edr19 1619) + (edr20 1620) (edr21 1621) (edr22 1622) (edr23 1623) + (edr24 1624) (edr25 1625) (edr26 1626) (edr27 1627) + (edr28 1628) (edr29 1629) (edr30 1630) (edr31 1631) + (edr32 1632) (edr33 1636) (edr34 1634) (edr35 1635) + (edr36 1636) (edr37 1637) (edr38 1638) (edr39 1639) + (edr40 1640) (edr41 1641) (edr42 1642) (edr43 1643) + (edr44 1644) (edr45 1645) (edr46 1646) (edr47 1647) + (edr48 1648) (edr49 1649) (edr50 1650) (edr51 1651) + (edr52 1652) (edr53 1653) (edr54 1654) (edr55 1655) + (edr56 1656) (edr57 1657) (edr58 1658) (edr59 1659) + (edr60 1660) (edr61 1661) (edr62 1662) (edr63 1663) + + (iamlr0 1664) (iamlr1 1665) (iamlr2 1666) (iamlr3 1667) + (iamlr4 1668) (iamlr5 1669) (iamlr6 1670) (iamlr7 1671) + (iamlr8 1672) (iamlr9 1673) (iamlr10 1674) (iamlr11 1675) + (iamlr12 1676) (iamlr13 1677) (iamlr14 1678) (iamlr15 1679) + (iamlr16 1680) (iamlr17 1681) (iamlr18 1682) (iamlr19 1683) + (iamlr20 1684) (iamlr21 1685) (iamlr22 1686) (iamlr23 1687) + (iamlr24 1688) (iamlr25 1689) (iamlr26 1690) (iamlr27 1691) + (iamlr28 1692) (iamlr29 1693) (iamlr30 1694) (iamlr31 1695) + (iamlr32 1696) (iamlr33 1697) (iamlr34 1698) (iamlr35 1699) + (iamlr36 1700) (iamlr37 1701) (iamlr38 1702) (iamlr39 1703) + (iamlr40 1704) (iamlr41 1705) (iamlr42 1706) (iamlr43 1707) + (iamlr44 1708) (iamlr45 1709) (iamlr46 1710) (iamlr47 1711) + (iamlr48 1712) (iamlr49 1713) (iamlr50 1714) (iamlr51 1715) + (iamlr52 1716) (iamlr53 1717) (iamlr54 1718) (iamlr55 1719) + (iamlr56 1720) (iamlr57 1721) (iamlr58 1722) (iamlr59 1723) + (iamlr60 1724) (iamlr61 1725) (iamlr62 1726) (iamlr63 1727) + + (iampr0 1728) (iampr1 1729) (iampr2 1730) (iampr3 1731) + (iampr4 1732) (iampr5 1733) (iampr6 1734) (iampr7 1735) + (iampr8 1736) (iampr9 1737) (iampr10 1738) (iampr11 1739) + (iampr12 1740) (iampr13 1741) (iampr14 1742) (iampr15 1743) + (iampr16 1744) (iampr17 1745) (iampr18 1746) (iampr19 1747) + (iampr20 1748) (iampr21 1749) (iampr22 1750) (iampr23 1751) + (iampr24 1752) (iampr25 1753) (iampr26 1754) (iampr27 1755) + (iampr28 1756) (iampr29 1757) (iampr30 1758) (iampr31 1759) + (iampr32 1760) (iampr33 1761) (iampr34 1762) (iampr35 1763) + (iampr36 1764) (iampr37 1765) (iampr38 1766) (iampr39 1767) + (iampr40 1768) (iampr41 1769) (iampr42 1770) (iampr43 1771) + (iampr44 1772) (iampr45 1773) (iampr46 1774) (iampr47 1775) + (iampr48 1776) (iampr49 1777) (iampr50 1778) (iampr51 1779) + (iampr52 1780) (iampr53 1781) (iampr54 1782) (iampr55 1783) + (iampr56 1784) (iampr57 1785) (iampr58 1786) (iampr59 1787) + (iampr60 1788) (iampr61 1789) (iampr62 1790) (iampr63 1791) + + (damlr0 1792) (damlr1 1793) (damlr2 1794) (damlr3 1795) + (damlr4 1796) (damlr5 1797) (damlr6 1798) (damlr7 1799) + (damlr8 1800) (damlr9 1801) (damlr10 1802) (damlr11 1803) + (damlr12 1804) (damlr13 1805) (damlr14 1806) (damlr15 1807) + (damlr16 1808) (damlr17 1809) (damlr18 1810) (damlr19 1811) + (damlr20 1812) (damlr21 1813) (damlr22 1814) (damlr23 1815) + (damlr24 1816) (damlr25 1817) (damlr26 1818) (damlr27 1819) + (damlr28 1820) (damlr29 1821) (damlr30 1822) (damlr31 1823) + (damlr32 1824) (damlr33 1825) (damlr34 1826) (damlr35 1827) + (damlr36 1828) (damlr37 1829) (damlr38 1830) (damlr39 1831) + (damlr40 1832) (damlr41 1833) (damlr42 1834) (damlr43 1835) + (damlr44 1836) (damlr45 1837) (damlr46 1838) (damlr47 1839) + (damlr48 1840) (damlr49 1841) (damlr50 1842) (damlr51 1843) + (damlr52 1844) (damlr53 1845) (damlr54 1846) (damlr55 1847) + (damlr56 1848) (damlr57 1849) (damlr58 1850) (damlr59 1851) + (damlr60 1852) (damlr61 1853) (damlr62 1854) (damlr63 1855) + + (dampr0 1856) (dampr1 1857) (dampr2 1858) (dampr3 1859) + (dampr4 1860) (dampr5 1861) (dampr6 1862) (dampr7 1863) + (dampr8 1864) (dampr9 1865) (dampr10 1866) (dampr11 1867) + (dampr12 1868) (dampr13 1869) (dampr14 1870) (dampr15 1871) + (dampr16 1872) (dampr17 1873) (dampr18 1874) (dampr19 1875) + (dampr20 1876) (dampr21 1877) (dampr22 1878) (dampr23 1879) + (dampr24 1880) (dampr25 1881) (dampr26 1882) (dampr27 1883) + (dampr28 1884) (dampr29 1885) (dampr30 1886) (dampr31 1887) + (dampr32 1888) (dampr33 1889) (dampr34 1890) (dampr35 1891) + (dampr36 1892) (dampr37 1893) (dampr38 1894) (dampr39 1895) + (dampr40 1896) (dampr41 1897) (dampr42 1898) (dampr43 1899) + (dampr44 1900) (dampr45 1901) (dampr46 1902) (dampr47 1903) + (dampr48 1904) (dampr49 1905) (dampr50 1906) (dampr51 1907) + (dampr52 1908) (dampr53 1909) (dampr54 1910) (dampr55 1911) + (dampr56 1912) (dampr57 1913) (dampr58 1914) (dampr59 1915) + (dampr60 1916) (dampr61 1917) (dampr62 1918) (dampr63 1919) + + (amcr 1920) (stbar 1921) (mmcr 1922) + (iamvr1 1925) (damvr1 1927) + (cxnr 1936) (ttbr 1937) (tplr 1938) (tppr 1939) + (tpxr 1940) + (timerh 1952) (timerl 1953) (timerd 1954) + (dcr 2048) (brr 2049) (nmar 2050) (btbr 2051) + + (ibar0 2052) (ibar1 2053) (ibar2 2054) (ibar3 2055) + (dbar0 2056) (dbar1 2057) (dbar2 2058) (dbar3 2059) + + (dbdr00 2060) (dbdr01 2061) (dbdr02 2062) (dbdr03 2063) + (dbdr10 2064) (dbdr11 2065) (dbdr12 2066) (dbdr13 2067) + (dbdr20 2068) (dbdr21 2069) (dbdr22 2070) (dbdr23 2071) + (dbdr30 2072) (dbdr31 2073) (dbdr32 2074) (dbdr33 2075) + + (dbmr00 2076) (dbmr01 2077) (dbmr02 2078) (dbmr03 2079) + (dbmr10 2080) (dbmr11 2081) (dbmr12 2082) (dbmr13 2083) + (dbmr20 2084) (dbmr21 2085) (dbmr22 2086) (dbmr23 2087) + (dbmr30 2088) (dbmr31 2089) (dbmr32 2090) (dbmr33 2091) + + (cpcfr 2304) (cpcr 2305) (cpsr 2306) (cptr 2307) + (cphsr0 2308) (cphsr1 2309) (cpesr0 2320) (cpesr1 2321) + (cpemr0 2322) (cpemr1 2323) + + (iperr0 2324) (iperr1 2325) (ipjsr 2326) (ipjrr 2327) + (ipcsr0 2336) (ipcsr1 2337) (ipcwer0 2338) (ipcwer1 2339) + (ipcwr 2340) + + (mbhsr 2352) (mbssr 2353) (mbrsr 2354) (mbsdr 2355) + (mbrdr 2356) (mbsmr 2357) (mbstr0 2359) (mbstr1 2360) + + (slpr 2368) (sldr 2369) (slhsr 2370) (sltr 2371) + (slwr 2372) + + (ihsr8 3848) (ihsr9 3849) (ihsr10 3850) + ) +) + +(define-hardware + (name h-spr) + (comment "special purpose registers") + (attrs PROFILE) + (type register UWI (4096)) + (indices extern-keyword spr-names) + (get (index) (c-call UWI "@cpu@_h_spr_get_handler" index)) + (set (index newval) (c-call VOID "@cpu@_h_spr_set_handler" index newval)) +) + +(define-pmacro (spr-pcsr) (reg h-spr 1)) +(define-pmacro (spr-bpcsr) (reg h-spr 2)) +(define-pmacro (spr-lr) (reg h-spr 272)) +(define-pmacro (spr-lcr) (reg h-spr 273)) +(define-pmacro (spr-iacc0h) (reg h-spr 280)) +(define-pmacro (spr-iacc0l) (reg h-spr 281)) +(define-pmacro (spr-sr0) (reg h-spr 768)) +(define-pmacro (spr-sr1) (reg h-spr 769)) +(define-pmacro (spr-sr2) (reg h-spr 770)) +(define-pmacro (spr-sr3) (reg h-spr 771)) + +; Accumulator guard. Actually a subset of the SPR registers, but those SPRs +; are read-only in most insns. This hardware element is used by those insns +; which have direct access (mwtaccg, mrdaccg). +(define-keyword + (name accg-names) + (print-name h-accg) + (prefix "") + (values + (accg0 0)(accg1 1)(accg2 2)(accg3 3) + (accg4 4)(accg5 5)(accg6 6)(accg7 7) + (accg8 8)(accg9 9)(accg10 10)(accg11 11) + (accg12 12)(accg13 13)(accg14 14)(accg15 15) + (accg16 16)(accg17 17)(accg18 18)(accg19 19) + (accg20 20)(accg21 21)(accg22 22)(accg23 23) + (accg24 24)(accg25 25)(accg26 26)(accg27 27) + (accg28 28)(accg29 29)(accg30 30)(accg31 31) + (accg32 32)(accg33 33)(accg34 34)(accg35 35) + (accg36 36)(accg37 37)(accg38 38)(accg39 39) + (accg40 40)(accg41 41)(accg42 42)(accg43 43) + (accg44 44)(accg45 45)(accg46 46)(accg47 47) + (accg48 48)(accg49 49)(accg50 50)(accg51 51) + (accg52 52)(accg53 53)(accg54 54)(accg55 55) + (accg56 56)(accg57 57)(accg58 58)(accg59 59) + (accg60 60)(accg61 61)(accg62 62)(accg63 63) + ) +) + +(define-hardware + (name h-accg) + (comment "accumulator guard") + (attrs PROFILE VIRTUAL) + (type register UWI (64)) + (indices extern-keyword accg-names) + (get (index) + (and (reg h-spr (add index 1472)) #xff)) + (set (index newval) + (set (raw-reg UWI h-spr (add index 1472)) (and newval #xff))) +) + +; 40 bit accumulator. Composed of ACCG and ACC registers concatenated, but +; referenced more often as the composed 40 bits. +(define-keyword + (name acc-names) + (print-name h-acc40) + (prefix "") + (values +(acc0 0)(acc1 1)(acc2 2)(acc3 3)(acc4 4)(acc5 5)(acc6 6)(acc7 7) +(acc8 8)(acc9 9)(acc10 10)(acc11 11)(acc12 12)(acc13 13)(acc14 14)(acc15 15) +(acc16 16)(acc17 17)(acc18 18)(acc19 19)(acc20 20)(acc21 21)(acc22 22)(acc23 23) +(acc24 24)(acc25 25)(acc26 26)(acc27 27)(acc28 28)(acc29 29)(acc30 30)(acc31 31) +(acc32 32)(acc33 33)(acc34 34)(acc35 35)(acc36 36)(acc37 37)(acc38 38)(acc39 39) +(acc40 40)(acc41 41)(acc42 42)(acc43 43)(acc44 44)(acc45 45)(acc46 46)(acc47 47) +(acc48 48)(acc49 49)(acc50 50)(acc51 51)(acc52 52)(acc53 53)(acc54 54)(acc55 55) +(acc56 56)(acc57 57)(acc58 58)(acc59 59)(acc60 60)(acc61 61)(acc62 62)(acc63 63) + ) +) + +(define-hardware + (name h-acc40S) + (comment "40 bit signed accumulator") + (attrs PROFILE VIRTUAL) + (type register DI (64)) + (indices extern-keyword acc-names) + ; The accumlator is made up of two 32 bit registers, accgi/acci. + ; We want to extract this as a combined 40 signed bits + (get (index) + (or DI + (sll DI (ext DI (trunc QI (reg h-spr (add index 1472)))) + 32) + (zext DI (reg h-spr (add index 1408))))) + ; Bits 40-63 are not written. raw-reg is used to bypass read-only restrictions + ; on ACC and ACCG registers + (set (index newval) + (sequence () + (c-call VOID "frv_check_spr_write_access" (add index 1408)) + (set (raw-reg UWI h-spr + (add index 1472)) (and (srl newval 32) #xff)) + (set (raw-reg UWI h-spr + (add index 1408)) (trunc USI newval)))) +) + +(define-hardware + (name h-acc40U) + (comment "40 bit unsigned accumulator") + (attrs PROFILE VIRTUAL) + (type register UDI (64)) + (indices extern-keyword acc-names) + ; The accumlator is made up of two 32 bit registers, accgi/acci. + ; We want to extract this as a combined 40 unsigned bits + (get (index) + (or DI + (sll DI (zext DI (reg h-spr (add index 1472))) 32) + (zext DI (reg h-spr (add index 1408))))) + ; Bits 40-63 are not written. raw-reg is used to bypass read-only restrictions + ; on ACC and ACCG registers + (set (index newval) + (sequence () + (c-call VOID "frv_check_spr_write_access" (add index 1408)) + (set (raw-reg UWI h-spr + (add index 1472)) (and (srl newval 32) #xff)) + (set (raw-reg UWI h-spr + (add index 1408)) (trunc USI newval)))) +) +; 64-bit signed accumulator. Composed of iacc0h and iacc0l registers +; concatenated, but referenced more often as the composed 64 bits. +(define-keyword + ; This is totally hokey -- I have to have an index! + (name iacc0-names) + (print-name h-iacc0) + (prefix "") + (values (iacc0 0)) +) + +(define-hardware + (name h-iacc0) + (comment "64 bit signed accumulator") + (attrs PROFILE VIRTUAL (MACH fr400,fr450)) + (type register DI (1)) + (indices extern-keyword iacc0-names) + ; The single 64-bit integer accumulator is made up of two 32 bit + ; registers, iacc0h and iacc0l. We want to extract this as a + ; combined 64 signed bits. + (get (idx) (or DI (sll DI (ext DI (spr-iacc0h)) 32) (zext DI (spr-iacc0l)))) + (set (idx newval) + (sequence () + (set (spr-iacc0h) (trunc SI (srl newval 32))) + (set (spr-iacc0l) (trunc SI newval)))) +) + +; Integer condition code registers (CCR) +; +; The individual sub registers bits of the CCR are referenced more often than +; the entire register so set them directly. We can assemble the +; entire register when necessary. +; +(define-keyword + (name iccr-names) + (print-name h-iccr) + (prefix "") + (values (icc0 0) (icc1 1) (icc2 2) (icc3 3)) +) + +(define-hardware + (name h-iccr) + (comment "Integer condition code registers") + (attrs PROFILE) + (type register UQI (4)) + (indices extern-keyword iccr-names) +) + +; Floating point condition code registers (CCR) +; +; The individual sub registers bits of the CCR are referenced more often than +; the entire register so set them directly. We can assemble the +; entire register when necessary. +; +(define-keyword + (name fccr-names) + (print-name h-fccr) + (prefix "") + (values (fcc0 0) (fcc1 1) (fcc2 2) (fcc3 3)) +) + +(define-hardware + (name h-fccr) + (comment "Floating point condition code registers") + (attrs PROFILE) + (type register UQI (4)) + (indices extern-keyword fccr-names) +) + +; C condition code registers (CCCR) +; +(define-keyword + (name cccr-names) + (print-name h-cccr) + (prefix "") + (values (cc0 0) (cc1 1) (cc2 2) (cc3 3) (cc4 4) (cc5 5) (cc6 6) (cc7 7)) +) + +(define-hardware + (name h-cccr) + (comment "Condition code registers") + (attrs PROFILE) + (type register UQI (8)) + (indices extern-keyword cccr-names) +) + +; Dummy hardware used to define packing bit on insns +; +(define-hardware + (name h-pack) + (comment "Packing bit dummy hardware") + (type immediate (UINT 1)) + (values keyword "" (("" 1) (".p" 0) (".P" 0))) +) +; Dummy hardware used to define hint field for branches always taken +; +(define-hardware + (name h-hint-taken) + (comment "Branch taken hint dummy hardware") + (type immediate (UINT 1)) + ; The order of these is important. We want '2' to get written by default, + ; but we also want the docoder/disassembler to allow the values '0', '1' and + ; '3'. + (values keyword "" (("" 2) ("" 0) ("" 1) ("" 3))) +) +; Dummy hardware used to define hint field for branches never taken +; +(define-hardware + (name h-hint-not-taken) + (comment "Branch not taken hint dummy hardware") + (type immediate (UINT 1)) + ; The order of these is important. We want '0' to get written by default, + ; but we also want the docoder/disassembler to allow the values '1', '2' and + ; '3'. + (values keyword "" (("" 0) ("" 1) ("" 2) ("" 3))) +) + +; Instruction Operands. +; These entries provide a layer between the assembler and the raw hardware +; description, and are used to refer to hardware elements in the semantic +; code. Usually there's a bit of over-specification, but in more complicated +; instruction sets there isn't. + +; FRV specific operand attributes: + +(define-attr + (for operand) + (type boolean) + (name HASH-PREFIX) + (comment "immediates have an optional '#' prefix") +) + +; ??? Convention says this should be o-sr, but then the insn definitions +; should refer to o-sr which is clumsy. The "o-" could be implicit, but +; then it should be implicit for all the symbols here, but then there would +; be confusion between (f-)simm8 and (h-)simm8. +; So for now the rule is exactly as it appears here. + +; dnmop: define-normal-mode-operand: temporary, pending potential removal +; of modes from h/w. +(define-pmacro (dnmop xname xcomment xattrs xtype xindex xmode) + (define-operand + (name xname) + (comment xcomment) + (.splice attrs (.unsplice xattrs)) + (type xtype) + (index xindex) + (mode xmode) + ) +) + +; dnpmop: define-normal-parsed-mode-operand: Normal mode operand with parse handler +(define-pmacro (dnpmop xname xcomment xattrs xtype xindex xmode xparse) + (define-operand + (name xname) + (comment xcomment) + (.splice attrs (.unsplice xattrs)) + (type xtype) + (index xindex) + (mode xmode) + (handlers (parse xparse)) + ) +) + +(dnop pack "packing bit" () h-pack f-pack) + +(dnmop GRi "source register 1" () h-gr f-GRi SI) +(dnmop GRj "source register 2" () h-gr f-GRj SI) +(dnmop GRk "destination register" () h-gr f-GRk SI) +(dnmop GRkhi "destination register" () h-gr_hi f-GRk UHI) +(dnmop GRklo "destination register" () h-gr_lo f-GRk UHI) +(dnpmop GRdoublek "destination register" () h-gr_double f-GRk DI "even_register") +(dnmop ACC40Si "signed accumulator" () h-acc40S f-ACC40Si DI) +(dnmop ACC40Ui "unsigned accumulator" () h-acc40U f-ACC40Ui UDI) +(dnmop ACC40Sk "target accumulator" () h-acc40S f-ACC40Sk DI) +(dnmop ACC40Uk "target accumulator" () h-acc40U f-ACC40Uk UDI) +(dnmop ACCGi "source register" () h-accg f-ACCGi UWI) +(dnmop ACCGk "target register" () h-accg f-ACCGk UWI) + +(dnmop CPRi "source register" ((MACH frv)) h-cpr f-CPRi SI) +(dnmop CPRj "source register" ((MACH frv)) h-cpr f-CPRj SI) +(dnmop CPRk "destination register" ((MACH frv)) h-cpr f-CPRk SI) +(dnpmop CPRdoublek "destination register" ((MACH frv)) h-cpr_double f-CPRk DI "even_register") + +; floating point operands +(dnmop FRinti "source register 1" () h-fr_int f-FRi SI) +(dnmop FRintj "source register 2" () h-fr_int f-FRj SI) +(dnmop FRintk "target register" () h-fr_int f-FRk SI) +(dnmop FRi "source register 1" () h-fr f-FRi SF) +(dnmop FRj "source register 2" () h-fr f-FRj SF) +(dnmop FRk "destination register" () h-fr f-FRk SF) +(dnmop FRkhi "destination register" () h-fr_hi f-FRk UHI) +(dnmop FRklo "destination register" () h-fr_lo f-FRk UHI) +(dnpmop FRdoublei "source register 1" () h-fr_double f-FRi DF "even_register") +(dnpmop FRdoublej "source register 2" () h-fr_double f-FRj DF "even_register") +(dnpmop FRdoublek "target register" () h-fr_double f-FRk DF "even_register") + +(dnop CRi "source register 1" () h-cccr f-CRi) +(dnop CRj "source register 2" () h-cccr f-CRj) +(dnop CRj_int "destination register" () h-cccr f-CRj_int) +(dnop CRj_float "destination register" () h-cccr f-CRj_float) +(dnop CRk "destination register" () h-cccr f-CRk) +(dnop CCi "condition register" () h-cccr f-CCi) + +(dnop ICCi_1 "condition register" () h-iccr f-ICCi_1) +(dnop ICCi_2 "condition register" () h-iccr f-ICCi_2) +(dnop ICCi_3 "condition register" () h-iccr f-ICCi_3) +(dnop FCCi_1 "condition register" () h-fccr f-FCCi_1) +(dnop FCCi_2 "condition register" () h-fccr f-FCCi_2) +(dnop FCCi_3 "condition register" () h-fccr f-FCCi_3) +(dnop FCCk "condition register" () h-fccr f-FCCk) + +(dnop eir "exception insn reg" () h-uint f-eir) +(dnop s10 "10 bit signed immediate" (HASH-PREFIX) h-sint f-s10) +(dnop u16 "16 bit unsigned immediate" (HASH-PREFIX) h-uint f-u16) +(dnop s16 "16 bit signed immediate" (HASH-PREFIX) h-sint f-s16) +(dnop s6 "6 bit signed immediate" (HASH-PREFIX) h-sint f-s6) +(dnop s6_1 "6 bit signed immediate" (HASH-PREFIX) h-sint f-s6_1) +(dnop u6 "6 bit unsigned immediate" (HASH-PREFIX) h-uint f-u6) +(dnop s5 "5 bit signed immediate" (HASH-PREFIX) h-sint f-s5) +(dnop cond "conditional arithmetic" (HASH-PREFIX) h-uint f-cond) +(dnop ccond "lr branch condition" (HASH-PREFIX) h-uint f-ccond) +(dnop hint "2 bit branch predictor" (HASH-PREFIX) h-uint f-hint) +(dnop hint_taken "2 bit branch predictor" () h-hint-taken f-hint) +(dnop hint_not_taken "2 bit branch predictor" () h-hint-not-taken f-hint) + +(dnop LI "link indicator" () h-uint f-LI) +(dnop lock "cache lock indicator" (HASH-PREFIX) h-uint f-lock) +(dnop debug "debug mode indicator" (HASH-PREFIX) h-uint f-debug) +(dnop ae "all entries indicator" (HASH-PREFIX) h-uint f-ae) + +(dnop label16 "18 bit pc relative address" () h-iaddr f-label16) + +(dnop LRAE "Load Real Address E flag" () h-uint f-LRAE) +(dnop LRAD "Load Real Address D flag" () h-uint f-LRAD) +(dnop LRAS "Load Real Address S flag" () h-uint f-LRAS) + +(dnop TLBPRopx "TLB Probe operation number" () h-uint f-TLBPRopx) +(dnop TLBPRL "TLB Probe L flag" () h-uint f-TLBPRL) + +(define-operand + (name A0) + (comment "A==0 operand of mclracc") + (attrs) + (type h-uint) + (index f-A) + (mode USI) + (handlers (parse "A0")) +) + +(define-operand + (name A1) + (comment "A==1 operand of mclracc") + (attrs) + (type h-uint) + (index f-A) + (mode USI) + (handlers (parse "A1")) +) + +(define-operand + (name FRintieven) + (comment "(even) source register 1") + (attrs) + (type h-fr_int) + (index f-FRi) + (mode SI) + (handlers (parse "even_register")) +) + +(define-operand + (name FRintjeven) + (comment "(even) source register 2") + (attrs) + (type h-fr_int) + (index f-FRj) + (mode SI) + (handlers (parse "even_register")) +) + +(define-operand + (name FRintkeven) + (comment "(even) target register") + (attrs) + (type h-fr_int) + (index f-FRk) + (mode SI) + (handlers (parse "even_register")) +) + +(define-operand + (name d12) + (comment "12 bit signed immediate") + (attrs) + (type h-sint) + (index f-d12) + (handlers (parse "d12")) +) + +(define-operand + (name s12) + (comment "12 bit signed immediate") + (attrs HASH-PREFIX) + (type h-sint) + (index f-d12) + (handlers (parse "s12")) +) + +(define-operand + (name u12) + (comment "12 bit signed immediate") + (attrs HASH-PREFIX) + (type h-sint) + (index f-u12) + (handlers (parse "u12")) +) + +(define-operand + (name spr) + (comment "special purpose register") + (attrs) + (type h-spr) + (index f-spr) + (handlers (parse "spr") (print "spr")) +) + +(define-operand + (name ulo16) + (comment "16 bit unsigned immediate, for #lo()") + (attrs) + (type h-uint) + (index f-u16) + (handlers (parse "ulo16") (print "lo")) +) + +(define-operand + (name slo16) + (comment "16 bit unsigned immediate, for #lo()") + (attrs) + (type h-sint) + (index f-s16) + (handlers (parse "uslo16") (print "lo")) +) + +(define-operand + (name uhi16) + (comment "16 bit unsigned immediate, for #hi()") + (attrs) + (type h-uint) + (index f-u16) + (handlers (parse "uhi16") (print "hi")) +) + +(define-operand + (name label24) + (comment "26 bit pc relative address") + (attrs) + (type h-iaddr) + (index f-label24) + (mode SI) + (handlers (parse "call_label")) +) + +; operands representing hardware +; +(dnop psr_esr "PSR.ESR bit" (SEM-ONLY) h-psr_esr f-nil) +(dnop psr_s "PSR.S bit" (SEM-ONLY) h-psr_s f-nil) +(dnop psr_ps "PSR.PS bit" (SEM-ONLY) h-psr_ps f-nil) +(dnop psr_et "PSR.ET bit" (SEM-ONLY) h-psr_et f-nil) + +(dnop bpsr_bs "BPSR.BS bit" (SEM-ONLY) h-bpsr_bs f-nil) +(dnop bpsr_bet "BPSR.BET bit" (SEM-ONLY) h-bpsr_bet f-nil) + +(dnop tbr_tba "TBR.TBA" (SEM-ONLY) h-tbr_tba f-nil) +(dnop tbr_tt "TBR.TT" (SEM-ONLY) h-tbr_tt f-nil) + +; Null operands +; +(define-pmacro (ICCi_1-null) (f-ICCi_1-null 0)) +(define-pmacro (ICCi_2-null) (f-ICCi_2-null 0)) +(define-pmacro (ICCi_3-null) (f-ICCi_3-null 0)) +(define-pmacro (FCCi_1-null) (f-FCCi_1-null 0)) +(define-pmacro (FCCi_2-null) (f-FCCi_2-null 0)) +(define-pmacro (FCCi_3-null) (f-FCCi_3-null 0)) +(define-pmacro (rs-null) (f-rs-null 0)) +(define-pmacro (GRi-null) (f-GRi-null 0)) +(define-pmacro (GRj-null) (f-GRj-null 0)) +(define-pmacro (GRk-null) (f-GRk-null 0)) +(define-pmacro (FRi-null) (f-FRi-null 0)) +(define-pmacro (FRj-null) (f-FRj-null 0)) +(define-pmacro (ACCj-null) (f-ACCj-null 0)) +(define-pmacro (rd-null) (f-rd-null 0)) +(define-pmacro (cond-null) (f-cond-null 0)) +(define-pmacro (ccond-null) (f-ccond-null 0)) +(define-pmacro (s12-null) (f-s12-null 0)) +(define-pmacro (label16-null) (f-label16-null 0)) +(define-pmacro (misc-null-1) (f-misc-null-1 0)) +(define-pmacro (misc-null-2) (f-misc-null-2 0)) +(define-pmacro (misc-null-3) (f-misc-null-3 0)) +(define-pmacro (misc-null-4) (f-misc-null-4 0)) +(define-pmacro (misc-null-5) (f-misc-null-5 0)) +(define-pmacro (misc-null-6) (f-misc-null-6 0)) +(define-pmacro (misc-null-7) (f-misc-null-7 0)) +(define-pmacro (misc-null-8) (f-misc-null-8 0)) +(define-pmacro (misc-null-9) (f-misc-null-9 0)) +(define-pmacro (misc-null-10) (f-misc-null-10 0)) +(define-pmacro (misc-null-11) (f-misc-null-11 0)) + +(define-pmacro (LRA-null) (f-LRA-null 0)) +(define-pmacro (TLBPR-null) (f-TLBPR-null 0)) + +(define-pmacro (LI-on) (f-LI-on 1)) +(define-pmacro (LI-off) (f-LI-off 0)) + +; Instruction definitions. +; +; Notes: +; - dni is short for "define-normal-instruction" +; - Macros are used to represent each insn format. These should be used as much +; as possible unless an insn has exceptional behaviour +; + +; Commonly used Macros +; +; Specific registers +; + +; Integer condition code manipulation +; +(define-pmacro (set-z-and-n icc x) + (if (eq x 0) + (set icc (or (and icc #x7) #x4)) + (if (lt x 0) + (set icc (or (and icc #xb) #x8)) + (set icc (and icc #x3)))) +) + +(define-pmacro (set-n icc val) + (if (eq val 0) + (set icc (and icc #x7)) + (set icc (or icc #x8))) +) + +(define-pmacro (set-z icc val) + (if (eq val 0) + (set icc (and icc #xb)) + (set icc (or icc #x4))) +) + +(define-pmacro (set-v icc val) + (if (eq val 0) + (set icc (and icc #xd)) + (set icc (or icc #x2))) +) + +(define-pmacro (set-c icc val) + (if (eq val 0) + (set icc (and icc #xe)) + (set icc (or icc #x1))) +) + +(define-pmacro (nbit icc) + (trunc BI (srl (and icc #x8) 3)) +) + +(define-pmacro (zbit icc) + (trunc BI (srl (and icc #x4) 2)) +) + +(define-pmacro (vbit icc) + (trunc BI (srl (and icc #x2) 1)) +) + +(define-pmacro (cbit icc) + (trunc BI (and icc #x1)) +) + +(define-pmacro (ebit icc) + (trunc BI (srl (and icc #x8) 3)) +) + +(define-pmacro (lbit icc) + (trunc BI (srl (and icc #x4) 2)) +) + +(define-pmacro (gbit icc) + (trunc BI (srl (and icc #x2) 1)) +) + +(define-pmacro (ubit icc) + (trunc BI (and icc #x1)) +) + +; FRV insns +; +; +; Format: INT, Logic, Shift r-r +; +(define-pmacro (int-logic-r-r name operation op ope comment) + (dni name + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str name "$pack $GRi,$GRj,$GRk") + (+ pack GRk op GRi (ICCi_1-null) ope GRj) + (set GRk (operation GRi GRj)) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(int-logic-r-r add add OP_00 OPE2_00 "add reg/reg") +(int-logic-r-r sub sub OP_00 OPE2_04 "sub reg/reg") +(int-logic-r-r and and OP_01 OPE2_00 "and reg/reg") +(int-logic-r-r or or OP_01 OPE2_02 "or reg/reg") +(int-logic-r-r xor xor OP_01 OPE2_04 "xor reg/reg") + +(dni not + ("not") + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + ("not$pack $GRj,$GRk") + (+ pack GRk OP_01 (rs-null) (ICCi_1-null) OPE2_06 GRj) + (set GRk (inv GRj)) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) +) + +(dni sdiv + "signed division" + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + "sdiv$pack $GRi,$GRj,$GRk" + (+ pack GRk OP_00 GRi (ICCi_1-null) OPE2_0E GRj) + (sequence () + (c-call VOID "@cpu@_signed_integer_divide" + GRi GRj (index-of GRk) 0) + (clobber GRk)) + ((fr400 (unit u-idiv)) (fr450 (unit u-idiv)) + (fr500 (unit u-idiv)) (fr550 (unit u-idiv))) +) + +(dni nsdiv + "non excepting signed division" + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) NON-EXCEPTING + (MACH simple,tomcat,fr500,fr550,frv)) + "nsdiv$pack $GRi,$GRj,$GRk" + (+ pack GRk OP_01 GRi (ICCi_1-null) OPE2_0E GRj) + (sequence () + (c-call VOID "@cpu@_signed_integer_divide" + GRi GRj (index-of GRk) 1) + (clobber GRk)) + ((fr500 (unit u-idiv)) (fr550 (unit u-idiv))) +) + +(dni udiv + "unsigned division reg/reg" + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + "udiv$pack $GRi,$GRj,$GRk" + (+ pack GRk OP_00 GRi (ICCi_1-null) OPE2_0F GRj) + (sequence () + (c-call VOID "@cpu@_unsigned_integer_divide" + GRi GRj (index-of GRk) 0) + (clobber GRk)) + ((fr400 (unit u-idiv)) (fr450 (unit u-idiv)) + (fr500 (unit u-idiv)) (fr550 (unit u-idiv))) +) + +(dni nudiv + "non excepting unsigned division" + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) NON-EXCEPTING + (MACH simple,tomcat,fr500,fr550,frv)) + "nudiv$pack $GRi,$GRj,$GRk" + (+ pack GRk OP_01 GRi (ICCi_1-null) OPE2_0F GRj) + (sequence () + (c-call VOID "@cpu@_unsigned_integer_divide" + GRi GRj (index-of GRk) 1) + (clobber GRk)) + ((fr500 (unit u-idiv)) (fr550 (unit u-idiv))) +) + +; Multiplication +; +(define-pmacro (multiply-r-r name signop op ope comment) + (dni name + (comment) + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str name "$pack $GRi,$GRj,$GRdoublek") + (+ pack GRdoublek op GRi (ICCi_1-null) ope GRj) + (set GRdoublek (mul DI (signop DI GRi) (signop DI GRj))) + ((fr400 (unit u-imul)) (fr450 (unit u-imul)) + (fr500 (unit u-imul)) (fr550 (unit u-imul))) + ) +) + +(multiply-r-r smul ext OP_00 OPE2_08 "signed multiply reg/reg") +(multiply-r-r umul zext OP_00 OPE2_0A "unsigned multiply reg/reg") + +; Multiplication with integer accumulator IACC +; + +(define-pmacro (iacc-set value) + (set (reg h-iacc0 0) value)) + +(define-pmacro (iacc-add value) + (set (reg h-iacc0 0) + (cond DI + ((andif (andif (gt value 0) (gt (reg h-iacc0 0) 0)) + (lt (sub DI #x7fffffffffffffff value) (reg h-iacc0 0))) + ; Positive overflow + (const DI #x7fffffffffffffff)) + ((andif (andif (lt value 0) (lt (reg h-iacc0 0) 0)) + (gt (sub DI #x8000000000000000 value) (reg h-iacc0 0))) + ; Negative overflow + (const DI #x8000000000000000)) + (else + (add DI (reg h-iacc0 0) value)))) +) + +(define-pmacro (iacc-sub value) + (set (reg h-iacc0 0) + (cond DI + ((andif (andif (lt value 0) (gt (reg h-iacc0 0) 0)) + (lt (add DI #x7fffffffffffffff value) (reg h-iacc0 0))) + ; Positive overflow + (const DI #x7fffffffffffffff)) + ((andif (andif (gt value 0) (lt (reg h-iacc0 0) 0)) + (gt (add DI #x8000000000000000 value) (reg h-iacc0 0))) + ; Negative overflow + (const DI #x8000000000000000)) + (else + (sub DI (reg h-iacc0 0) value)))) +) + +(define-pmacro (iacc-multiply-r-r name operation op ope comment) + (dni name + (comment) + ((UNIT IACC) (MACH fr400,fr450) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) AUDIO) + (.str name "$pack $GRi,$GRj") + (+ pack (rd-null) op GRi ope GRj) + ((.sym iacc- operation) (mul DI (ext DI GRi) (ext DI GRj))) + ((fr400 (unit u-integer)) (fr450 (unit u-integer))) + ) +) + +(iacc-multiply-r-r smu set OP_46 OPE1_05 "Signed multiply reg/reg/iacc") +(iacc-multiply-r-r smass add OP_46 OPE1_06 "Signed multiply/add reg/reg/iacc") +(iacc-multiply-r-r smsss sub OP_46 OPE1_07 "Signed multiply/sub reg/reg/iacc") + +(define-pmacro (int-shift-r-r name op ope comment) + (dni name + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str name "$pack $GRi,$GRj,$GRk") + (+ pack GRk op GRi (ICCi_1-null) ope GRj) + (set GRk (name GRi (and GRj #x1f))) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(int-shift-r-r sll OP_01 OPE2_08 "shift left logical reg/reg") +(int-shift-r-r srl OP_01 OPE2_0A "shift right logical reg/reg") +(int-shift-r-r sra OP_01 OPE2_0C "shift right arith reg/reg") + +(dni slass + "shift left arith reg/reg with saturation" + ((UNIT IALL) (MACH fr400,fr450) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) AUDIO) + "slass$pack $GRi,$GRj,$GRk" + (+ pack GRk OP_46 GRi OPE1_02 GRj) + (set GRk (c-call SI "@cpu@_shift_left_arith_saturate" GRi GRj)) + () +) + +(dni scutss + "Integer accumulator cut with saturation" + ((UNIT I0) (MACH fr400,fr450) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) AUDIO) + "scutss$pack $GRj,$GRk" + (+ pack GRk OP_46 (rs-null) OPE1_04 GRj) + (set GRk (c-call SI "@cpu@_iacc_cut" (reg h-iacc0 0) GRj)) + () +) + +(define-pmacro (scan-semantics arg1 arg2 targ) + (sequence ((WI tmp1) (WI tmp2)) + (set tmp1 arg1) + (set tmp2 (sra arg2 1)) + (set targ (c-call WI "@cpu@_scan_result" (xor tmp1 tmp2)))) +) + +(dni scan + "scan" + ((UNIT SCAN) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + "scan$pack $GRi,$GRj,$GRk" + (+ pack GRk OP_0B GRi (ICCi_1-null) OPE2_00 GRj) + (scan-semantics GRi GRj GRk) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) +) + +; Format: conditional INT, Logic, Shift r-r +; +(define-pmacro (conditional-int-logic name operation op ope comment) + (dni name + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) CONDITIONAL) + (.str name "$pack $GRi,$GRj,$GRk,$CCi,$cond") + (+ pack GRk op GRi CCi cond ope GRj) + (if (eq CCi (or cond 2)) + (set GRk (operation GRi GRj))) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(conditional-int-logic cadd add OP_58 OPE4_0 "conditional add") +(conditional-int-logic csub sub OP_58 OPE4_1 "conditional sub") +(conditional-int-logic cand and OP_5A OPE4_0 "conditional and") +(conditional-int-logic cor or OP_5A OPE4_1 "conditional or") +(conditional-int-logic cxor xor OP_5A OPE4_2 "conditional xor") + +(dni cnot + "conditional not" + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) CONDITIONAL) + "cnot$pack $GRj,$GRk,$CCi,$cond" + (+ pack GRk OP_5A (rs-null) CCi cond OPE4_3 GRj) + (if (eq CCi (or cond 2)) + (set GRk (inv GRj))) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) +) + +(dni csmul + "conditional signed multiply" + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) CONDITIONAL) + "csmul$pack $GRi,$GRj,$GRdoublek,$CCi,$cond" + (+ pack GRdoublek OP_58 GRi CCi cond OPE4_2 GRj) + (if (eq CCi (or cond 2)) + (set GRdoublek (mul DI (ext DI GRi) (ext DI GRj)))) + ((fr400 (unit u-imul)) (fr450 (unit u-imul)) + (fr500 (unit u-imul)) (fr550 (unit u-imul))) +) + +(dni csdiv + "conditional signed division" + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) CONDITIONAL) + "csdiv$pack $GRi,$GRj,$GRk,$CCi,$cond" + (+ pack GRk OP_58 GRi CCi cond OPE4_3 GRj) + (if (eq CCi (or cond 2)) + (sequence () + (c-call VOID "@cpu@_signed_integer_divide" + GRi GRj (index-of GRk) 0) + (clobber GRk))) + ((fr400 (unit u-idiv)) (fr450 (unit u-idiv)) + (fr500 (unit u-idiv)) (fr550 (unit u-idiv))) +) + +(dni cudiv + "conditional unsigned division" + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) CONDITIONAL) + "cudiv$pack $GRi,$GRj,$GRk,$CCi,$cond" + (+ pack GRk OP_59 GRi CCi cond OPE4_3 GRj) + (if (eq CCi (or cond 2)) + (sequence () + (c-call VOID "@cpu@_unsigned_integer_divide" + GRi GRj (index-of GRk) 0) + (clobber GRk))) + ((fr400 (unit u-idiv)) (fr450 (unit u-idiv)) + (fr500 (unit u-idiv)) (fr550 (unit u-idiv))) +) + +(define-pmacro (conditional-shift name operation op ope comment) + (dni name + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) CONDITIONAL) + (.str name "$pack $GRi,$GRj,$GRk,$CCi,$cond") + (+ pack GRk op GRi CCi cond ope GRj) + (if (eq CCi (or cond 2)) + (set GRk (operation GRi (and GRj #x1f)))) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(conditional-shift csll sll OP_5C OPE4_0 "conditional shift left logical") +(conditional-shift csrl srl OP_5C OPE4_1 "conditional shift right logical") +(conditional-shift csra sra OP_5C OPE4_2 "conditional shift right arith") + +(dni cscan + "conditional scan" + ((UNIT SCAN) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) CONDITIONAL) + "cscan$pack $GRi,$GRj,$GRk,$CCi,$cond" + (+ pack GRk OP_65 GRi CCi cond OPE4_3 GRj) + (if (eq CCi (or cond 2)) + (scan-semantics GRi GRj GRk)) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) +) + +; Format: INT, Logic, Shift, cc r-r +; +(define-pmacro (int-arith-cc-semantics operation icc) + (sequence ((BI tmp) (QI cc) (SI result)) + (set cc icc) + (set tmp ((.sym operation -oflag) GRi GRj (const 0))) + (set-v cc tmp) + (set tmp ((.sym operation -cflag) GRi GRj (const 0))) + (set-c cc tmp) + (set result (operation GRi GRj)) + (set-z-and-n cc result) + (set GRk result) + (set icc cc)) +) + +(define-pmacro (int-arith-cc-r-r name operation op ope comment) + (dni name + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str name "$pack $GRi,$GRj,$GRk,$ICCi_1") + (+ pack GRk op GRi ICCi_1 ope GRj) + (int-arith-cc-semantics operation ICCi_1) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(int-arith-cc-r-r addcc add OP_00 OPE2_01 "add reg/reg, set icc") +(int-arith-cc-r-r subcc sub OP_00 OPE2_05 "sub reg/reg, set icc") + +(define-pmacro (int-logic-cc-semantics op icc) + (sequence ((SI tmp)) + (set tmp (op GRi GRj)) + (set GRk tmp) + (set-z-and-n icc tmp)) +) + +(define-pmacro (int-logic-cc-r-r name op ope comment) + (dni (.sym name cc) + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str (.sym name cc) "$pack $GRi,$GRj,$GRk,$ICCi_1") + (+ pack GRk op GRi ICCi_1 ope GRj) + (int-logic-cc-semantics name ICCi_1) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(int-logic-cc-r-r and OP_01 OPE2_01 "and reg/reg, set icc") +(int-logic-cc-r-r or OP_01 OPE2_03 "or reg/reg, set icc") +(int-logic-cc-r-r xor OP_01 OPE2_05 "xor reg/reg, set icc") + +(define-pmacro (int-shift-cc-semantics op l-r icc) + (sequence ((WI shift) (SI tmp) (QI cc)) + (set shift (and GRj #x1f)) + (set cc (c-call QI (.str "@cpu@_set_icc_for_shift_" l-r) + GRi shift icc)) + (set tmp (op GRi shift)) + (set GRk tmp) + (set-z-and-n cc tmp) + (set icc cc)) +) + +(define-pmacro (int-shift-cc-r-r name l-r op ope comment) + (dni (.sym name cc) + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str (.sym name cc) "$pack $GRi,$GRj,$GRk,$ICCi_1") + (+ pack GRk op GRi ICCi_1 ope GRj) + (int-shift-cc-semantics name l-r ICCi_1) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(int-shift-cc-r-r sll left OP_01 OPE2_09 "shift left logical reg/reg,set icc") +(int-shift-cc-r-r srl right OP_01 OPE2_0B "shift right logical reg/reg,set icc") +(int-shift-cc-r-r sra right OP_01 OPE2_0D "shift right arith reg/reg,set icc") + +(define-pmacro (multiply-cc-semantics signop arg1 arg2 targ icc) + (sequence ((DI tmp) (QI cc)) + (set cc icc) + (set tmp (mul DI (signop DI arg1) (signop DI arg2))) + (set-n cc (srl DI tmp 63)) + (set-z cc (eq tmp 0)) + (set targ tmp) + (set icc cc)) +) + +(define-pmacro (multiply-cc-r-r name signop op ope comment) + (dni name + (comment) + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str name "$pack $GRi,$GRj,$GRdoublek,$ICCi_1") + (+ pack GRdoublek op GRi ICCi_1 ope GRj) + (multiply-cc-semantics signop GRi GRj GRdoublek ICCi_1) + ((fr400 (unit u-imul)) (fr450 (unit u-imul)) + (fr500 (unit u-imul)) (fr550 (unit u-imul))) + ) +) + +(multiply-cc-r-r smulcc ext OP_00 OPE2_09 "signed multiply reg/reg") +(multiply-cc-r-r umulcc zext OP_00 OPE2_0B "unsigned multiply reg/reg") + + +; Format: conditional INT, Logic, Shift, cc r-r +; +(define-pmacro (conditional-int-arith-cc name operation op ope comment) + (dni name + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) CONDITIONAL) + (.str name "$pack $GRi,$GRj,$GRk,$CCi,$cond") + (+ pack GRk op GRi CCi cond ope GRj) + (if (eq CCi (or cond 2)) + (int-arith-cc-semantics operation + (reg h-iccr (and (index-of CCi) 3)))) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(conditional-int-arith-cc caddcc add OP_59 OPE4_0 "add, set icc") +(conditional-int-arith-cc csubcc sub OP_59 OPE4_1 "sub, set icc") + +(dni csmulcc + "conditional signed multiply and set condition code" + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) CONDITIONAL) + "csmulcc$pack $GRi,$GRj,$GRdoublek,$CCi,$cond" + (+ pack GRdoublek OP_59 GRi CCi cond OPE4_2 GRj) + (if (eq CCi (or cond 2)) + (multiply-cc-semantics ext GRi GRj GRdoublek + (reg h-iccr (and (index-of CCi) 3)))) + ((fr400 (unit u-imul)) (fr450 (unit u-imul)) + (fr500 (unit u-imul)) (fr550 (unit u-imul))) +) + +(define-pmacro (conditional-int-logic-cc name operation op ope comment) + (dni name + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) CONDITIONAL) + (.str name "$pack $GRi,$GRj,$GRk,$CCi,$cond") + (+ pack GRk op GRi CCi cond ope GRj) + (if (eq CCi (or cond 2)) + (int-logic-cc-semantics operation + (reg h-iccr (and (index-of CCi) 3)))) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(conditional-int-logic-cc candcc and OP_5B OPE4_0 "conditional and, set icc") +(conditional-int-logic-cc corcc or OP_5B OPE4_1 "conditional or , set icc") +(conditional-int-logic-cc cxorcc xor OP_5B OPE4_2 "conditional xor, set icc") + +(define-pmacro (conditional-int-shift-cc name l-r op ope comment) + (dni (.sym c name cc) + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) CONDITIONAL) + (.str (.sym c name cc) "$pack $GRi,$GRj,$GRk,$CCi,$cond") + (+ pack GRk op GRi CCi cond ope GRj) + (if (eq CCi (or cond 2)) + (int-shift-cc-semantics name l-r + (reg h-iccr (and (index-of CCi) 3)))) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(conditional-int-shift-cc sll left OP_5D OPE4_0 "shift left logical, set icc") +(conditional-int-shift-cc srl right OP_5D OPE4_1 "shift right logical, set icc") +(conditional-int-shift-cc sra right OP_5D OPE4_2 "shift right arith , set icc") + +; Add and subtract with carry +; +(define-pmacro (int-arith-x-r-r name operation op ope comment) + (dni name + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str name "$pack $GRi,$GRj,$GRk,$ICCi_1") + (+ pack GRk op GRi ICCi_1 ope GRj) + (set GRk ((.sym operation c) GRi GRj (cbit ICCi_1))) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(int-arith-x-r-r addx add OP_00 OPE2_02 "Add reg/reg, with carry") +(int-arith-x-r-r subx sub OP_00 OPE2_06 "Sub reg/reg, with carry") + +(define-pmacro (int-arith-x-cc-r-r name operation op ope comment) + (dni name + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str name "$pack $GRi,$GRj,$GRk,$ICCi_1") + (+ pack GRk op GRi ICCi_1 ope GRj) + (sequence ((WI tmp) (QI cc)) + (set cc ICCi_1) + (set tmp ((.sym operation c) GRi GRj (cbit cc))) + (set-v cc ((.sym operation -oflag) GRi GRj (cbit cc))) + (set-c cc ((.sym operation -cflag) GRi GRj (cbit cc))) + (set-z-and-n cc tmp) + (set GRk tmp) + (set ICCi_1 cc)) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(int-arith-x-cc-r-r addxcc add OP_00 OPE2_03 "Add reg/reg, use/set carry") +(int-arith-x-cc-r-r subxcc sub OP_00 OPE2_07 "Sub reg/reg, use/set carry") +; Add and subtract with saturation +; +(define-pmacro (int-arith-ss-r-r name operation op ope comment) + (dni name + (comment) + ((UNIT IALL) (MACH fr400,fr450) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) AUDIO) + (.str name "$pack $GRi,$GRj,$GRk") + (+ pack GRk op GRi ope GRj) + (sequence () + (set GRk (operation GRi GRj)) + (if ((.sym operation -oflag) GRi GRj (const 0)) + ; Overflow, saturate. + ; Sign of result will be + ; same as sign of first operand. + (set GRk + (cond SI + ((gt GRi 0) (const #x7fffffff)) + ((lt GRi 0) (const #x80000000)) + (else (const 0))))) + ) + ((fr400 (unit u-integer)) (fr450 (unit u-integer))) + ) +) + +(int-arith-ss-r-r addss add OP_46 OPE1_00 "add reg/reg, with saturation") +(int-arith-ss-r-r subss sub OP_46 OPE1_01 "sub reg/reg, with saturation") + +; Format: INT, Logic, Shift r-simm +; +(define-pmacro (int-logic-r-simm name operation op comment) + (dni name + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str name "$pack $GRi,$s12,$GRk") + (+ pack GRk op GRi s12) + (set GRk (operation GRi s12)) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(int-logic-r-simm addi add OP_10 "add reg/immed") +(int-logic-r-simm subi sub OP_14 "sub reg/immed") +(int-logic-r-simm andi and OP_20 "and reg/immed") +(int-logic-r-simm ori or OP_22 "or reg/immed") +(int-logic-r-simm xori xor OP_24 "xor reg/immed") + +(dni sdivi + "signed division reg/immed" + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + "sdivi$pack $GRi,$s12,$GRk" + (+ pack GRk OP_1E GRi s12) + (sequence () + (c-call VOID "@cpu@_signed_integer_divide" + GRi s12 (index-of GRk) 0) + (clobber GRk)) + ((fr400 (unit u-idiv)) (fr450 (unit u-idiv)) + (fr500 (unit u-idiv)) (fr550 (unit u-idiv))) +) + +(dni nsdivi + "non excepting signed division reg/immed" + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) NON-EXCEPTING + (MACH simple,tomcat,fr500,fr550,frv)) + "nsdivi$pack $GRi,$s12,$GRk" + (+ pack GRk OP_2E GRi s12) + (sequence () + (c-call VOID "@cpu@_signed_integer_divide" + GRi s12 (index-of GRk) 1) + (clobber GRk)) + ((fr500 (unit u-idiv)) (fr550 (unit u-idiv))) +) + +(dni udivi + "unsigned division reg/immed" + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + "udivi$pack $GRi,$s12,$GRk" + (+ pack GRk OP_1F GRi s12) + (sequence () + (c-call VOID "@cpu@_unsigned_integer_divide" + GRi s12 (index-of GRk) 0) + (clobber GRk)) + ((fr400 (unit u-idiv)) (fr450 (unit u-idiv)) + (fr500 (unit u-idiv)) (fr550 (unit u-idiv))) +) + +(dni nudivi + "non excepting unsigned division reg/immed" + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) NON-EXCEPTING + (MACH simple,tomcat,fr500,fr550,frv)) + "nudivi$pack $GRi,$s12,$GRk" + (+ pack GRk OP_2F GRi s12) + (sequence () + (c-call VOID "@cpu@_unsigned_integer_divide" + GRi s12 (index-of GRk) 1) + (clobber GRk)) + ((fr500 (unit u-idiv)) (fr550 (unit u-idiv))) +) + +(define-pmacro (multiply-r-simm name signop op comment) + (dni name + (comment) + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str name "$pack $GRi,$s12,$GRdoublek") + (+ pack GRdoublek op GRi s12) + (set GRdoublek (mul DI (signop DI GRi) (signop DI s12))) + ((fr400 (unit u-imul)) (fr450 (unit u-imul)) + (fr500 (unit u-imul)) (fr550 (unit u-imul))) + ) +) + +(multiply-r-simm smuli ext OP_18 "signed multiply reg/immed") +(multiply-r-simm umuli zext OP_1A "unsigned multiply reg/immed") + +(define-pmacro (int-shift-r-simm name op comment) + (dni (.sym name i) + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str (.sym name i) "$pack $GRi,$s12,$GRk") + (+ pack GRk op GRi s12) + (set GRk (name GRi (and s12 #x1f))) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(int-shift-r-simm sll OP_28 "shift left logical reg/immed") +(int-shift-r-simm srl OP_2A "shift right logical reg/immed") +(int-shift-r-simm sra OP_2C "shift right arith reg/immed") + +(dni scani + "scan immediate" + ((UNIT SCAN) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + "scani$pack $GRi,$s12,$GRk" + (+ pack GRk OP_47 GRi s12) + (scan-semantics GRi s12 GRk) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) +) + +; Format: INT, Logic, Shift cc r-simm +; +(define-pmacro (int-arith-cc-r-simm name operation op comment) + (dni name + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str name "$pack $GRi,$s10,$GRk,$ICCi_1") + (+ pack GRk op GRi ICCi_1 s10) + (sequence ((BI tmp) (QI cc) (SI result)) + (set cc ICCi_1) + (set tmp ((.sym operation -oflag) GRi s10 (const 0))) + (set-v cc tmp) + (set tmp ((.sym operation -cflag) GRi s10 (const 0))) + (set-c cc tmp) + (set result (operation GRi s10)) + (set-z-and-n cc result) + (set GRk result) + (set ICCi_1 cc)) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(int-arith-cc-r-simm addicc add OP_11 "add reg/immed, set icc") +(int-arith-cc-r-simm subicc sub OP_15 "sub reg/immed, set icc") + +(define-pmacro (int-logic-cc-r-simm name op comment) + (dni (.sym name icc) + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str (.sym name icc) "$pack $GRi,$s10,$GRk,$ICCi_1") + (+ pack GRk op GRi ICCi_1 s10) + (sequence ((SI tmp)) + (set tmp (name GRi s10)) + (set GRk tmp) + (set-z-and-n ICCi_1 tmp)) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(int-logic-cc-r-simm and OP_21 "and reg/immed, set icc") +(int-logic-cc-r-simm or OP_23 "or reg/immed, set icc") +(int-logic-cc-r-simm xor OP_25 "xor reg/immed, set icc") + +(define-pmacro (multiply-cc-r-simm name signop op comment) + (dni name + (comment) + ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR550-MAJOR I-2) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str name "$pack $GRi,$s10,$GRdoublek,$ICCi_1") + (+ pack GRdoublek op GRi ICCi_1 s10) + (multiply-cc-semantics signop GRi s10 GRdoublek ICCi_1) + ((fr400 (unit u-imul)) (fr450 (unit u-imul)) + (fr500 (unit u-imul)) (fr550 (unit u-imul))) + ) +) + +(multiply-cc-r-simm smulicc ext OP_19 "signed multiply reg/immed") +(multiply-cc-r-simm umulicc zext OP_1B "unsigned multiply reg/immed") + +(define-pmacro (int-shift-cc-r-simm name l-r op comment) + (dni (.sym name icc) + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str (.sym name icc) "$pack $GRi,$s10,$GRk,$ICCi_1") + (+ pack GRk op GRi ICCi_1 s10) + (sequence ((WI shift) (SI tmp) (QI cc)) + (set shift (and s10 #x1f)) + (set cc (c-call QI (.str "@cpu@_set_icc_for_shift_" l-r) + GRi shift ICCi_1)) + (set tmp (name GRi shift)) + (set GRk tmp) + (set-z-and-n cc tmp) + (set ICCi_1 cc)) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(int-shift-cc-r-simm sll left OP_29 "shift left logical reg/immed, set icc") +(int-shift-cc-r-simm srl right OP_2B "shift right logical reg/immed, set icc") +(int-shift-cc-r-simm sra right OP_2D "shift right arith reg/immed, set icc") + +(define-pmacro (int-arith-x-r-simm name operation op comment) + (dni name + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str name "$pack $GRi,$s10,$GRk,$ICCi_1") + (+ pack GRk op GRi ICCi_1 s10) + (set GRk ((.sym operation c) GRi s10 (cbit ICCi_1))) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(int-arith-x-r-simm addxi add OP_12 "Add reg/immed, with carry") +(int-arith-x-r-simm subxi sub OP_16 "Sub reg/immed, with carry") + +(define-pmacro (int-arith-x-cc-r-simm name operation op comment) + (dni name + (comment) + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + (.str name "$pack $GRi,$s10,$GRk,$ICCi_1") + (+ pack GRk op GRi ICCi_1 s10) + (sequence ((WI tmp) (QI cc)) + (set cc ICCi_1) + (set tmp ((.sym operation c) GRi s10 (cbit cc))) + (set-v cc ((.sym operation -oflag) GRi s10 (cbit cc))) + (set-c cc ((.sym operation -cflag) GRi s10 (cbit cc))) + (set-z-and-n cc tmp) + (set GRk tmp) + (set ICCi_1 cc)) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) + ) +) + +(int-arith-x-cc-r-simm addxicc add OP_13 "Add reg/immed, with carry") +(int-arith-x-cc-r-simm subxicc sub OP_17 "Sub reg/immed, with carry") + +; Byte compare insns + +(dni cmpb + "Compare bytes" + ((UNIT IALL) (MACH fr400,fr450,fr550) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + "cmpb$pack $GRi,$GRj,$ICCi_1" + (+ pack (GRk-null) OP_00 GRi ICCi_1 OPE2_0C GRj) + (sequence ((QI cc)) + (set-n cc (eq (and GRi #xff000000) (and GRj #xff000000))) + (set-z cc (eq (and GRi #x00ff0000) (and GRj #x00ff0000))) + (set-v cc (eq (and GRi #x0000ff00) (and GRj #x0000ff00))) + (set-c cc (eq (and GRi #x000000ff) (and GRj #x000000ff))) + (set ICCi_1 cc)) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr550 (unit u-integer))) +) + +(dni cmpba + "OR of Compare bytes" + ((UNIT IALL) (MACH fr400,fr450,fr550) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + "cmpba$pack $GRi,$GRj,$ICCi_1" + (+ pack (GRk-null) OP_00 GRi ICCi_1 OPE2_0D GRj) + (sequence ((QI cc)) + (set cc 0) + (set-c cc + (orif (eq (and GRi #xff000000) (and GRj #xff000000)) + (orif (eq (and GRi #x00ff0000) (and GRj #x00ff0000)) + (orif (eq (and GRi #x0000ff00) + (and GRj #x0000ff00)) + (eq (and GRi #x000000ff) + (and GRj #x000000ff)))))) + (set ICCi_1 cc)) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr550 (unit u-integer))) +) + +; Format: Load immediate +; +(dni setlo + "set low order bits" + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + "setlo$pack $ulo16,$GRklo" + (+ pack GRk OP_3D (misc-null-4) u16) + (set GRklo u16) + ((fr400 (unit u-set-hilo)) (fr450 (unit u-set-hilo)) + (fr500 (unit u-set-hilo)) (fr550 (unit u-set-hilo))) +) + +(dni sethi + "set high order bits" + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + "sethi$pack $uhi16,$GRkhi" + (+ pack GRkhi OP_3E (misc-null-4) u16) + (set GRkhi u16) + ((fr400 (unit u-set-hilo)) (fr450 (unit u-set-hilo)) + (fr500 (unit u-set-hilo)) (fr550 (unit u-set-hilo))) +) + +(dni setlos + "set low order bits and extend sign" + ((UNIT IALL) (FR500-MAJOR I-1) (FR550-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + "setlos$pack $slo16,$GRk" + (+ pack GRk OP_3F (misc-null-4) s16) + (set GRk s16) + ((fr400 (unit u-integer)) (fr450 (unit u-integer)) + (fr500 (unit u-integer)) (fr550 (unit u-integer))) +) + +(define-pmacro (load-gr-r name mode op ope comment ann) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) + (FR400-MAJOR I-2) (FR450-MAJOR I-2)) + (.str name "$pack " ann "($GRi,$GRj),$GRk") + (+ pack GRk op GRi ope GRj) + (set GRk (c-call mode (.str "@cpu@_read_mem_" mode) pc (add GRi GRj))) + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + ) +) + +(dann ldann "ld annotation" SI "ld_annotation" "at") + +(load-gr-r ldsb QI OP_02 OPE1_00 "Load signed byte" "@") +(load-gr-r ldub UQI OP_02 OPE1_01 "Load unsigned byte" "@") +(load-gr-r ldsh HI OP_02 OPE1_02 "Load signed half" "@") +(load-gr-r lduh UHI OP_02 OPE1_03 "Load unsigned half" "@") +(load-gr-r ld SI OP_02 OPE1_04 "Load word" "$ldann") + +(define-pmacro (load-fr-r name mode op ope comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) + (FR400-MAJOR I-2) (FR450-MAJOR I-2) FR-ACCESS) + (.str name "$pack @($GRi,$GRj),$FRintk") + (+ pack FRintk op GRi ope GRj) + (set FRintk (c-call mode (.str "@cpu@_read_mem_" mode) pc (add GRi GRj))) + ((fr400 (unit u-fr-load)) (fr450 (unit u-fr-load)) + (fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) + ) +) + +(load-fr-r ldbf UQI OP_02 OPE1_08 "Load byte float") +(load-fr-r ldhf UHI OP_02 OPE1_09 "Load half float") +(load-fr-r ldf SI OP_02 OPE1_0A "Load word float") + +(define-pmacro (load-cpr-r name mode op ope reg attr comment) + (dni name + (comment) + ((UNIT LOAD) (FR500-MAJOR I-2) attr) + (.str name "$pack @($GRi,$GRj),$" reg "k") + (+ pack (.sym reg k) op GRi ope GRj) + (set (.sym reg k) + (c-call mode (.str "@cpu@_read_mem_" mode) pc (add GRi GRj))) + () + ) +) + +(load-cpr-r ldc SI OP_02 OPE1_0D CPR (MACH frv) "Load coprocessor word") + +; These correspond to enumerators in frv-sim.h +(define-pmacro (ne-UQI-size) 0) +(define-pmacro (ne-QI-size) 1) +(define-pmacro (ne-UHI-size) 2) +(define-pmacro (ne-HI-size) 3) +(define-pmacro (ne-SI-size) 4) +(define-pmacro (ne-DI-size) 5) +(define-pmacro (ne-XI-size) 6) + +(define-pmacro (ne-load-semantics base dispix targ idisp size is_float action) + (sequence ((BI do_op)) + (set do_op + (c-call BI "@cpu@_check_non_excepting_load" + (index-of base) dispix (index-of targ) + idisp size is_float)) + (if do_op action)) +) + +(define-pmacro (ne-load-gr-r name mode op ope size comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) NON-EXCEPTING + (MACH simple,tomcat,fr500,fr550,frv)) + (.str name "$pack @($GRi,$GRj),$GRk") + (+ pack GRk op GRi ope GRj) + (ne-load-semantics GRi (index-of GRj) GRk 0 size 0 + (set GRk + (c-call mode (.str "@cpu@_read_mem_" mode) + pc (add GRi GRj)))) + ((fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + ) +) + +(ne-load-gr-r nldsb QI OP_02 OPE1_20 (ne-QI-size) "Load signed byte") +(ne-load-gr-r nldub UQI OP_02 OPE1_21 (ne-UQI-size) "Load unsigned byte") +(ne-load-gr-r nldsh HI OP_02 OPE1_22 (ne-HI-size) "Load signed half") +(ne-load-gr-r nlduh UHI OP_02 OPE1_23 (ne-UHI-size) "Load unsigned half") +(ne-load-gr-r nld SI OP_02 OPE1_24 (ne-SI-size) "Load word") + +(define-pmacro (ne-load-fr-r name mode op ope size comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) NON-EXCEPTING FR-ACCESS + (MACH simple,tomcat,fr500,fr550,frv)) + (.str name "$pack @($GRi,$GRj),$FRintk") + (+ pack FRintk op GRi ope GRj) + (ne-load-semantics GRi (index-of GRj) FRintk 0 size 1 + (set FRintk + (c-call mode (.str "@cpu@_read_mem_" mode) + pc (add GRi GRj)))) + ((fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) + ) +) + +(ne-load-fr-r nldbf UQI OP_02 OPE1_28 (ne-UQI-size) "Load byte float") +(ne-load-fr-r nldhf UHI OP_02 OPE1_29 (ne-UHI-size) "Load half float") +(ne-load-fr-r nldf SI OP_02 OPE1_2A (ne-SI-size) "Load word float") + +; Semantics for a load-double insn +; +(define-pmacro (load-double-semantics not_gr mode regtype address arg) + (if (orif not_gr (ne (index-of (.sym regtype doublek)) 0)) + (sequence () + (set address (add GRi arg)) + (set (.sym regtype doublek) + (c-call mode (.str "@cpu@_read_mem_" mode) pc address)))) +) + +(define-pmacro (load-double-r-r + name not_gr mode op ope regtype attr profile comment ann) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) + (FR400-MAJOR I-2) (FR450-MAJOR I-2) attr) + (.str name "$pack " ann "($GRi,$GRj),$" regtype "doublek") + (+ pack (.sym regtype doublek) op GRi ope GRj) + (sequence ((WI address)) + (load-double-semantics not_gr mode regtype address GRj)) + profile + ) +) + +(dann lddann "ldd annotation" SI "ldd_annotation" "at") + +(load-double-r-r ldd 0 DI OP_02 OPE1_05 GR NA + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + "Load double word" "$lddann") +(load-double-r-r lddf 1 DF OP_02 OPE1_0B FR FR-ACCESS + ((fr400 (unit u-fr-load)) (fr450 (unit u-fr-load)) + (fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) + "Load double float" "@") +(load-double-r-r lddc 1 DI OP_02 OPE1_0E CPR (MACH frv) () + "Load coprocessor double" "@") + +(define-pmacro (ne-load-double-r-r + name not_gr mode op ope regtype size is_float attr profile + comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) NON-EXCEPTING attr + (MACH simple,tomcat,fr500,fr550,frv)) + (.str name "$pack @($GRi,$GRj),$" regtype "doublek") + (+ pack (.sym regtype doublek) op GRi ope GRj) + (sequence ((WI address)) + (ne-load-semantics GRi (index-of GRj) (.sym regtype doublek) + 0 size is_float + (load-double-semantics not_gr mode + regtype + address GRj))) + profile + ) +) + +(ne-load-double-r-r nldd 0 DI OP_02 OPE1_25 GR (ne-DI-size) 0 NA + ((fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) "Load double word") +(ne-load-double-r-r nlddf 1 DF OP_02 OPE1_2B FR (ne-DI-size) 1 FR-ACCESS + ((fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) "Load double float") + +; Semantics for a load-quad insn +; +(define-pmacro (load-quad-semantics regtype address arg) + (sequence () + (set address (add GRi arg)) + (c-call VOID (.str "@cpu@_load_quad_" regtype) + pc address (index-of (.sym regtype k)))) +) + +(define-pmacro (load-quad-r-r name op ope regtype attr profile comment) + (dni name + (comment) + ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) attr) + (.str name "$pack @($GRi,$GRj),$" regtype "k") + (+ pack (.sym regtype k) op GRi ope GRj) + (sequence ((WI address)) + (load-quad-semantics regtype address GRj)) + ; TODO regtype-k not referenced for profiling + profile + ) +) + +(load-quad-r-r ldq OP_02 OPE1_06 GR NA ((fr500 (unit u-gr-load))) + "Load quad word") +(load-quad-r-r ldqf OP_02 OPE1_0C FRint FR-ACCESS ((fr500 (unit u-fr-load))) + "Load quad float") +(load-quad-r-r ldqc OP_02 OPE1_0F CPR NA () "Load coprocessor quad") + +(define-pmacro (ne-load-quad-r-r + name op ope regtype size is_float attr profile comment) + (dni name + (comment) + ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) NON-EXCEPTING attr) + (.str name "$pack @($GRi,$GRj),$" regtype "k") + (+ pack (.sym regtype k) op GRi ope GRj) + (sequence ((WI address)) + (ne-load-semantics GRi (index-of GRj) (.sym regtype k) + 0 size is_float + (load-quad-semantics regtype address GRj))) + ; TODO regtype-k not referenced for profiling + profile + ) +) + +(ne-load-quad-r-r nldq OP_02 OPE1_26 GR (ne-XI-size) 0 NA + ((fr500 (unit u-gr-load))) "Load quad word") +(ne-load-quad-r-r nldqf OP_02 OPE1_2C FRint (ne-XI-size) 1 FR-ACCESS + ((fr500 (unit u-fr-load))) "Load quad float") + +(define-pmacro (load-gr-u-semantics mode) + (sequence ((UWI address)) + (set address (add GRi GRj)) + (set GRk (c-call mode (.str "@cpu@_read_mem_" mode) pc address)) + (if (ne (index-of GRi) (index-of GRk)) + (sequence () + (set GRi address) + (c-call VOID "@cpu@_force_update")))) +) + +(define-pmacro (load-gr-u name mode op ope comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) + (FR400-MAJOR I-2) (FR450-MAJOR I-2)) + (.str name "$pack @($GRi,$GRj),$GRk") + (+ pack GRk op GRi ope GRj) + (load-gr-u-semantics mode) + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + ) +) + +(load-gr-u ldsbu QI OP_02 OPE1_10 "Load signed byte, update index") +(load-gr-u ldubu UQI OP_02 OPE1_11 "Load unsigned byte, update index") +(load-gr-u ldshu HI OP_02 OPE1_12 "Load signed half, update index") +(load-gr-u lduhu UHI OP_02 OPE1_13 "Load unsigned half, update index") +(load-gr-u ldu SI OP_02 OPE1_14 "Load word, update index") + +(define-pmacro (ne-load-gr-u name mode op ope size comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) NON-EXCEPTING + (MACH simple,tomcat,fr500,fr550,frv)) + (.str name "$pack @($GRi,$GRj),$GRk") + (+ pack GRk op GRi ope GRj) + (ne-load-semantics GRi (index-of GRj) GRk 0 size 0 (load-gr-u-semantics mode)) + ((fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + ) +) + +(ne-load-gr-u nldsbu QI OP_02 OPE1_30 (ne-QI-size) "Load signed byte, update index") +(ne-load-gr-u nldubu UQI OP_02 OPE1_31 (ne-UQI-size) "Load unsigned byte, update index") +(ne-load-gr-u nldshu HI OP_02 OPE1_32 (ne-HI-size) "Load signed half, update index") +(ne-load-gr-u nlduhu UHI OP_02 OPE1_33 (ne-UHI-size) "Load unsigned half, update index") +(ne-load-gr-u nldu SI OP_02 OPE1_34 (ne-SI-size) "Load word, update index") + +(define-pmacro (load-non-gr-u-semantics mode regtype) + (sequence ((UWI address)) + (set address (add GRi GRj)) + (set (.sym regtype k) + (c-call mode (.str "@cpu@_read_mem_" mode) pc address)) + (set GRi address) + (c-call VOID "@cpu@_force_update")) +) + +(define-pmacro (load-fr-u name mode op ope comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) + (FR400-MAJOR I-2) (FR450-MAJOR I-2) FR-ACCESS) + (.str name "$pack @($GRi,$GRj),$FRintk") + (+ pack FRintk op GRi ope GRj) + (load-non-gr-u-semantics mode FRint) + ((fr400 (unit u-fr-load)) (fr450 (unit u-fr-load)) + (fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) + ) +) + +(load-fr-u ldbfu UQI OP_02 OPE1_18 "Load byte float, update index") +(load-fr-u ldhfu UHI OP_02 OPE1_19 "Load half float, update index") +(load-fr-u ldfu SI OP_02 OPE1_1A "Load word float, update index") + +(define-pmacro (load-cpr-u name mode op ope comment) + (dni name + (comment) + ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv)) + (.str name "$pack @($GRi,$GRj),$CPRk") + (+ pack CPRk op GRi ope GRj) + (load-non-gr-u-semantics mode CPR) + () + ) +) + +(load-cpr-u ldcu SI OP_02 OPE1_1D "Load coprocessor word float,update index") + +(define-pmacro (ne-load-non-gr-u name mode op ope regtype size comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) NON-EXCEPTING FR-ACCESS + (MACH simple,tomcat,fr500,fr550,frv)) + (.str name "$pack @($GRi,$GRj),$" regtype "k") + (+ pack (.sym regtype k) op GRi ope GRj) + (ne-load-semantics GRi (index-of GRj) (.sym regtype k) 0 size 1 + (load-non-gr-u-semantics mode regtype)) + ((fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) + ) +) + +(ne-load-non-gr-u nldbfu UQI OP_02 OPE1_38 FRint (ne-UQI-size) "Load byte float, update index") +(ne-load-non-gr-u nldhfu UHI OP_02 OPE1_39 FRint (ne-UHI-size) "Load half float, update index") +(ne-load-non-gr-u nldfu SI OP_02 OPE1_3A FRint (ne-SI-size) "Load word float, update index") + +(define-pmacro (load-double-gr-u-semantics) + (sequence ((WI address)) + (load-double-semantics 0 DI GR address GRj) + (if (ne (index-of GRi) (index-of GRdoublek)) + (sequence () + (set GRi address) + (c-call VOID "@cpu@_force_update")))) +) + +(define-pmacro (load-double-gr-u name op ope comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) + (FR400-MAJOR I-2) (FR450-MAJOR I-2)) + (.str name "$pack @($GRi,$GRj),$GRdoublek") + (+ pack GRdoublek op GRi ope GRj) + (load-double-gr-u-semantics) + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + ) +) + +(load-double-gr-u lddu OP_02 OPE1_15 "Load double word, update index") + +(define-pmacro (ne-load-double-gr-u name op ope size comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) NON-EXCEPTING + (MACH simple,tomcat,fr500,fr550,frv)) + (.str name "$pack @($GRi,$GRj),$GRdoublek") + (+ pack GRdoublek op GRi ope GRj) + (ne-load-semantics GRi (index-of GRj) GRdoublek 0 size 0 + (load-double-gr-u-semantics)) + ((fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + + ) +) + +(ne-load-double-gr-u nlddu OP_02 OPE1_35 (ne-DI-size) "Load double word, update index") + +(define-pmacro (load-double-non-gr-u-semantics mode regtype) + (sequence ((WI address)) + (load-double-semantics 1 mode regtype address GRj) + (set GRi address) + (c-call VOID "@cpu@_force_update")) +) + +(define-pmacro (load-double-non-gr-u + name mode op ope regtype attr profile comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) + (FR400-MAJOR I-2) (FR450-MAJOR I-2) attr) + (.str name "$pack @($GRi,$GRj),$" regtype "doublek") + (+ pack (.sym regtype doublek) op GRi ope GRj) + (load-double-non-gr-u-semantics mode regtype) + profile + ) +) + +(load-double-non-gr-u lddfu DF OP_02 OPE1_1B FR FR-ACCESS + ((fr400 (unit u-fr-load)) (fr450 (unit u-fr-load)) + (fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) + "Load double float, update index") +(load-double-non-gr-u lddcu DI OP_02 OPE1_1E CPR (MACH frv) + () "Load coprocessor double float, update index") + +(define-pmacro (ne-load-double-non-gr-u name mode op ope regtype size comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) NON-EXCEPTING FR-ACCESS + (MACH simple,tomcat,fr500,fr550,frv)) + (.str name "$pack @($GRi,$GRj),$" regtype "doublek") + (+ pack (.sym regtype doublek) op GRi ope GRj) + (ne-load-semantics GRi (index-of GRj) (.sym regtype doublek) 0 size 1 + (load-double-non-gr-u-semantics mode regtype)) + ((fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) + ) +) + +(ne-load-double-non-gr-u nlddfu DF OP_02 OPE1_3B FR (ne-DI-size) "Load double float, update index") + +(define-pmacro (load-quad-gr-u-semantics) + (sequence ((WI address)) + (load-quad-semantics GR address GRj) + (if (ne (index-of GRi) (index-of GRk)) + (sequence () + (set GRi address) + (c-call VOID "@cpu@_force_update")))) +) + +(define-pmacro (load-quad-gr-u name op ope comment) + (dni name + (comment) + ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv)) + (.str name "$pack @($GRi,$GRj),$GRk") + (+ pack GRk op GRi ope GRj) + (load-quad-gr-u-semantics) + ; TODO - GRk not referenced here for profiling + ((fr500 (unit u-gr-load))) + ) +) + +(load-quad-gr-u ldqu OP_02 OPE1_16 "Load quad word, update index") + +(define-pmacro (ne-load-quad-gr-u name op ope size comment) + (dni name + (comment) + ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) NON-EXCEPTING) + (.str name "$pack @($GRi,$GRj),$GRk") + (+ pack GRk op GRi ope GRj) + (ne-load-semantics GRi (index-of GRj) GRk 0 size 0 + (load-quad-gr-u-semantics)) + ; TODO - GRk not referenced here for profiling + ((fr500 (unit u-gr-load))) + ) +) + +(ne-load-quad-gr-u nldqu OP_02 OPE1_36 (ne-XI-size) "Load quad word, update index") + +(define-pmacro (load-quad-non-gr-u-semantics regtype) + (sequence ((WI address)) + (load-quad-semantics regtype address GRj) + (set GRi address) + (c-call VOID "@cpu@_force_update")) +) + +(define-pmacro (load-quad-non-gr-u name op ope regtype attr profile comment) + (dni name + (comment) + ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) attr) + (.str name "$pack @($GRi,$GRj),$" regtype "k") + (+ pack (.sym regtype k) op GRi ope GRj) + (load-quad-non-gr-u-semantics regtype) + profile + ) +) + +(load-quad-non-gr-u ldqfu OP_02 OPE1_1C FRint FR-ACCESS + ((fr500 (unit u-fr-load))) "Load quad float, update index") +(load-quad-non-gr-u ldqcu OP_02 OPE1_1F CPR NA + () "Load coprocessor quad word, update index") + +(define-pmacro (ne-load-quad-non-gr-u name op ope regtype size comment) + (dni name + (comment) + ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) NON-EXCEPTING FR-ACCESS) + (.str name "$pack @($GRi,$GRj),$" regtype "k") + (+ pack (.sym regtype k) op GRi ope GRj) + (ne-load-semantics GRi (index-of GRj) (.sym regtype k) 0 size 1 + (load-quad-non-gr-u-semantics regtype)) + ((fr500 (unit u-fr-load))) + ) +) + +(ne-load-quad-non-gr-u nldqfu OP_02 OPE1_3C FRint (ne-XI-size) "Load quad float,update index") + +(define-pmacro (load-r-simm name mode op regtype attr profile comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) + (FR400-MAJOR I-2) (FR450-MAJOR I-2) attr) + (.str name "$pack @($GRi,$d12),$" regtype "k") + (+ pack (.sym regtype k) op GRi d12) + (set (.sym regtype k) + (c-call mode (.str "@cpu@_read_mem_" mode) pc (add GRi d12))) + profile + ) +) + +(load-r-simm ldsbi QI OP_30 GR NA + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + "Load signed byte") +(load-r-simm ldshi HI OP_31 GR NA + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + "Load signed half") +(load-r-simm ldi SI OP_32 GR NA + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + "Load word") +(load-r-simm ldubi UQI OP_35 GR NA + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + "Load unsigned byte") +(load-r-simm lduhi UHI OP_36 GR NA + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + "Load unsigned half") + +(load-r-simm ldbfi UQI OP_38 FRint FR-ACCESS + ((fr400 (unit u-fr-load)) (fr450 (unit u-fr-load)) + (fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) + "Load byte float") +(load-r-simm ldhfi UHI OP_39 FRint FR-ACCESS + ((fr400 (unit u-fr-load)) (fr450 (unit u-fr-load)) + (fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) + "Load half float") +(load-r-simm ldfi SI OP_3A FRint FR-ACCESS + ((fr400 (unit u-fr-load)) (fr450 (unit u-fr-load)) + (fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) + "Load word float") + +(define-pmacro (ne-load-r-simm + name mode op regtype size is_float attr profile comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) NON-EXCEPTING attr + (MACH simple,tomcat,fr500,fr550,frv)) + (.str name "$pack @($GRi,$d12),$" regtype "k") + (+ pack (.sym regtype k) op GRi d12) + (ne-load-semantics GRi -1 (.sym regtype k) d12 size is_float + (set (.sym regtype k) + (c-call mode (.str "@cpu@_read_mem_" mode) + pc (add GRi d12)))) + profile + ) +) + +(ne-load-r-simm nldsbi QI OP_40 GR (ne-QI-size) 0 NA + ((fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) "Load signed byte") +(ne-load-r-simm nldubi UQI OP_41 GR (ne-UQI-size) 0 NA + ((fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) "Load unsigned byte") +(ne-load-r-simm nldshi HI OP_42 GR (ne-HI-size) 0 NA + ((fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) "Load signed half") +(ne-load-r-simm nlduhi UHI OP_43 GR (ne-UHI-size) 0 NA + ((fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) "Load unsigned half") +(ne-load-r-simm nldi SI OP_44 GR (ne-SI-size) 0 NA + ((fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) "Load word") + +(ne-load-r-simm nldbfi UQI OP_48 FRint (ne-UQI-size) 1 FR-ACCESS + ((fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) "Load byte float") +(ne-load-r-simm nldhfi UHI OP_49 FRint (ne-UHI-size) 1 FR-ACCESS + ((fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) "Load half float") +(ne-load-r-simm nldfi SI OP_4A FRint (ne-SI-size) 1 FR-ACCESS + ((fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) "Load word float") + +(define-pmacro (load-double-r-simm + name not_gr mode op regtype attr profile comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) + (FR400-MAJOR I-2) (FR450-MAJOR I-2) attr) + (.str name "$pack @($GRi,$d12),$" regtype "doublek") + (+ pack (.sym regtype doublek) op GRi d12) + (sequence ((WI address)) + (load-double-semantics not_gr mode regtype address d12)) + profile + ) +) + +(load-double-r-simm lddi 0 DI OP_33 GR NA + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + "Load double word") +(load-double-r-simm lddfi 1 DF OP_3B FR FR-ACCESS + ((fr400 (unit u-fr-load)) (fr450 (unit u-fr-load)) + (fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) + "Load double float") + +(define-pmacro (ne-load-double-r-simm + name not_gr mode op regtype size is_float attr profile comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) NON-EXCEPTING attr + (MACH simple,tomcat,fr500,fr550,frv)) + (.str name "$pack @($GRi,$d12),$" regtype "doublek") + (+ pack (.sym regtype doublek) op GRi d12) + (sequence ((WI address)) + (ne-load-semantics GRi -1 (.sym regtype doublek) + d12 size is_float + (load-double-semantics not_gr mode + regtype + address d12))) + profile + ) +) + +(ne-load-double-r-simm nlddi 0 DI OP_45 GR (ne-DI-size) 0 NA + ((fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) "Load double word") +(ne-load-double-r-simm nlddfi 1 DF OP_4B FR (ne-DI-size) 1 FR-ACCESS + ((fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) "Load double float") + +(define-pmacro (load-quad-r-simm name op regtype attr profile comment) + (dni name + (comment) + ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) attr) + (.str name "$pack @($GRi,$d12),$" regtype "k") + (+ pack (.sym regtype k) op GRi d12) + (sequence ((WI address)) + (load-quad-semantics regtype address d12)) + profile + ) +) + +(load-quad-r-simm ldqi OP_34 GR NA + ((fr500 (unit u-gr-load))) "Load quad word") +(load-quad-r-simm ldqfi OP_3C FRint FR-ACCESS + ((fr500 (unit u-fr-load))) "Load quad float") + +(define-pmacro (ne-load-quad-r-simm + name op regtype size is_float attr profile comment) + (dni name + (comment) + ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) NON-EXCEPTING attr) + (.str name "$pack @($GRi,$d12),$" regtype "k") + (+ pack (.sym regtype k) op GRi d12) + (sequence ((WI address)) + (ne-load-semantics GRi -1 (.sym regtype k) d12 size is_float + (load-quad-semantics regtype address d12))) + profile + ) +) + +(ne-load-quad-r-simm nldqfi OP_4C FRint (ne-XI-size) 1 FR-ACCESS + ((fr500 (unit u-fr-load))) "Load quad float") + +(define-pmacro (store-r-r name mode op ope reg attr profile comment) + (dni name + (comment) + ((UNIT STORE) (FR550-MAJOR I-4) (FR500-MAJOR I-3) + (FR400-MAJOR I-3) (FR450-MAJOR I-3) attr) + (.str name "$pack $" reg "k,@($GRi,$GRj)") + (+ pack (.sym reg k) op GRi ope GRj) + (c-call VOID (.str "@cpu@_write_mem_" mode) + pc (add GRi GRj) (.sym reg k)) + profile + ) +) + +(store-r-r stb QI OP_03 OPE1_00 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store unsigned byte") +(store-r-r sth HI OP_03 OPE1_01 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store unsigned half") +(store-r-r st SI OP_03 OPE1_02 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store word") + +(store-r-r stbf QI OP_03 OPE1_08 FRint FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store byte float") +(store-r-r sthf HI OP_03 OPE1_09 FRint FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store half float") +(store-r-r stf SI OP_03 OPE1_0A FRint FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store word float") + +(store-r-r stc SI OP_03 OPE1_25 CPR (MACH frv) () "Store coprocessor word") + +; Semantics for a store-double insn +; +(define-pmacro (store-double-semantics mode regtype address arg) + (sequence () + (set address (add GRi arg)) + (c-call VOID (.str "@cpu@_write_mem_" mode) + pc address (.sym regtype doublek))) +) + +(define-pmacro (store-double-r-r name mode op ope regtype attr profile comment) + (dni name + (comment) + ((UNIT STORE) (FR550-MAJOR I-4) (FR500-MAJOR I-3) + (FR400-MAJOR I-3) (FR450-MAJOR I-3) attr) + (.str name "$pack $" regtype "doublek,@($GRi,$GRj)") + (+ pack (.sym regtype doublek) op GRi ope GRj) + (sequence ((WI address)) + (store-double-semantics mode regtype address GRj)) + profile + ) +) + +(store-double-r-r std DI OP_03 OPE1_03 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store double word") +(store-double-r-r stdf DF OP_03 OPE1_0B FR FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store double float") + +(store-double-r-r stdc DI OP_03 OPE1_26 CPR (MACH frv) + () "Store coprocessor double word") + +; Semantics for a store-quad insn +; +(define-pmacro (store-quad-semantics regtype address arg) + (sequence () + (set address (add GRi arg)) + (c-call VOID (.str "@cpu@_store_quad_" regtype) + pc address (index-of (.sym regtype k)))) +) + +(define-pmacro (store-quad-r-r name op ope regtype attr profile comment) + (dni name + (comment) + ((UNIT STORE) (FR500-MAJOR I-3) (MACH frv) attr) + (.str name "$pack $" regtype "k,@($GRi,$GRj)") + (+ pack (.sym regtype k) op GRi ope GRj) + (sequence ((WI address)) + (store-quad-semantics regtype address GRj)) + profile + ) +) + +(store-quad-r-r stq OP_03 OPE1_04 GR NA + ((fr500 (unit u-gr-store))) "Store quad word") +(store-quad-r-r stqf OP_03 OPE1_0C FRint FR-ACCESS + ((fr500 (unit u-fr-store))) + "Store quad float") +(store-quad-r-r stqc OP_03 OPE1_27 CPR NA + () "Store coprocessor quad word") + +(define-pmacro (store-r-r-u name mode op ope regtype attr profile comment) + (dni name + (comment) + ((UNIT STORE) (FR550-MAJOR I-4) (FR500-MAJOR I-3) + (FR400-MAJOR I-3) (FR450-MAJOR I-3) attr) + (.str name "$pack $" regtype "k,@($GRi,$GRj)") + (+ pack (.sym regtype k) op GRi ope GRj) + (sequence ((UWI address)) + (set address (add GRi GRj)) + (c-call VOID (.str "@cpu@_write_mem_" mode) + pc address (.sym regtype k)) + (set GRi address)) + profile + ) +) + +(store-r-r-u stbu QI OP_03 OPE1_10 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store unsigned byte, update index") +(store-r-r-u sthu HI OP_03 OPE1_11 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store unsigned half, update index") +(store-r-r-u stu WI OP_03 OPE1_12 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store word, update index") + +(store-r-r-u stbfu QI OP_03 OPE1_18 FRint FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store byte float, update index") +(store-r-r-u sthfu HI OP_03 OPE1_19 FRint FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store half float, update index") +(store-r-r-u stfu SI OP_03 OPE1_1A FRint FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store word float, update index") + +(store-r-r-u stcu SI OP_03 OPE1_2D CPR (MACH frv) () + "Store coprocessor word, update index") + +(define-pmacro (store-double-r-r-u + name mode op ope regtype attr profile comment) + (dni name + (comment) + ((UNIT STORE) (FR550-MAJOR I-4) (FR500-MAJOR I-3) + (FR400-MAJOR I-3) (FR450-MAJOR I-3) attr) + (.str name "$pack $" regtype "doublek,@($GRi,$GRj)") + (+ pack (.sym regtype doublek) op GRi ope GRj) + (sequence ((WI address)) + (store-double-semantics mode regtype address GRj) + (set GRi address)) + profile + ) +) + +(store-double-r-r-u stdu DI OP_03 OPE1_13 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store double word, update index") +(store-double-r-r-u stdfu DF OP_03 OPE1_1B FR FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store double float,update index") +(store-double-r-r-u stdcu DI OP_03 OPE1_2E CPR (MACH frv) () + "Store coprocessor double word, update index") + +(define-pmacro (store-quad-r-r-u name op ope regtype attr profile comment) + (dni name + (comment) + ((UNIT STORE) (FR500-MAJOR I-3) (MACH frv) attr) + (.str name "$pack $" regtype "k,@($GRi,$GRj)") + (+ pack (.sym regtype k) op GRi ope GRj) + (sequence ((WI address)) + (store-quad-semantics regtype address GRj) + (set GRi address)) + profile + ) +) + +(store-quad-r-r-u stqu OP_03 OPE1_14 GR NA + ((fr500 (unit u-gr-store))) + "Store quad word, update index") +(store-quad-r-r-u stqfu OP_03 OPE1_1C FRint FR-ACCESS + ((fr500 (unit u-fr-store))) + "Store quad float, update index") +(store-quad-r-r-u stqcu OP_03 OPE1_2F CPR NA () + "Store coprocessor quad word, update index") + +(define-pmacro (conditional-load name mode op ope regtype profile comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) + (FR400-MAJOR I-2) (FR450-MAJOR I-2) CONDITIONAL) + (.str name "$pack @($GRi,$GRj),$" regtype "k,$CCi,$cond") + (+ pack (.sym regtype k) op GRi CCi cond ope GRj) + (if (eq CCi (or cond 2)) + (set (.sym regtype k) + (c-call mode (.str "@cpu@_read_mem_" mode) pc (add GRi GRj)))) + profile + ) +) + +(conditional-load cldsb QI OP_5E OPE4_0 GR + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + "Load signed byte") +(conditional-load cldub UQI OP_5E OPE4_1 GR + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + "Load unsigned byte") +(conditional-load cldsh HI OP_5E OPE4_2 GR + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + "Load signed half") +(conditional-load clduh UHI OP_5E OPE4_3 GR + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + "Load unsigned half") +(conditional-load cld SI OP_5F OPE4_0 GR + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + "Load word") + +(conditional-load cldbf UQI OP_60 OPE4_0 FRint + ((fr400 (unit u-fr-load)) (fr450 (unit u-fr-load)) + (fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) + "Load byte float") +(conditional-load cldhf UHI OP_60 OPE4_1 FRint + ((fr400 (unit u-fr-load)) (fr450 (unit u-fr-load)) + (fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) + "Load half float") +(conditional-load cldf SI OP_60 OPE4_2 FRint + ((fr400 (unit u-fr-load)) (fr450 (unit u-fr-load)) + (fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) + "Load word float") + +(define-pmacro (conditional-load-double + name not_gr mode op ope regtype attr profile comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) + (FR400-MAJOR I-2) (FR450-MAJOR I-2) CONDITIONAL attr) + (.str name "$pack @($GRi,$GRj),$" regtype "doublek,$CCi,$cond") + (+ pack (.sym regtype doublek) op GRi CCi cond ope GRj) + (if (eq CCi (or cond 2)) + (sequence ((WI address)) + (load-double-semantics not_gr mode regtype address GRj))) + profile + ) +) + +(conditional-load-double cldd 0 DI OP_5F OPE4_1 GR NA + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + "Load double word") +(conditional-load-double clddf 1 DF OP_60 OPE4_3 FR FR-ACCESS + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-fr-load))) + "Load double float") + +(dni cldq + "conditional load quad integer" + ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) CONDITIONAL) + "cldq$pack @($GRi,$GRj),$GRk,$CCi,$cond" + (+ pack GRk OP_5F GRi CCi cond OPE4_2 GRj) + (if (eq CCi (or cond 2)) + (sequence ((WI address)) + (load-quad-semantics GR address GRj))) + ((fr500 (unit u-gr-load))) +) + +(define-pmacro (conditional-load-gr-u name mode op ope comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) + (FR400-MAJOR I-2) (FR450-MAJOR I-2) CONDITIONAL) + (.str name "$pack @($GRi,$GRj),$GRk,$CCi,$cond") + (+ pack GRk op GRi CCi cond ope GRj) + (if (eq CCi (or cond 2)) + (sequence ((WI address)) + (set address (add GRi GRj)) + (set GRk + (c-call mode (.str "@cpu@_read_mem_" mode) + pc address)) + (if (ne (index-of GRi) (index-of GRk)) + (set GRi address)))) + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) + ) +) + +(conditional-load-gr-u cldsbu QI OP_61 OPE4_0 "Load signed byte, update") +(conditional-load-gr-u cldubu UQI OP_61 OPE4_1 "Load unsigned byte, update") +(conditional-load-gr-u cldshu HI OP_61 OPE4_2 "Load signed half, update") +(conditional-load-gr-u clduhu UHI OP_61 OPE4_3 "Load unsigned half, update") +(conditional-load-gr-u cldu SI OP_62 OPE4_0 "Load word, update") + +(define-pmacro (conditional-load-non-gr-u name mode op ope regtype comment) + (dni name + (comment) + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) + (FR400-MAJOR I-2) (FR450-MAJOR I-2) CONDITIONAL FR-ACCESS) + (.str name "$pack @($GRi,$GRj),$" regtype "k,$CCi,$cond") + (+ pack (.sym regtype k) op GRi CCi cond ope GRj) + (if (eq CCi (or cond 2)) + (sequence ((WI address)) + (set address (add GRi GRj)) + (set (.sym regtype k) + (c-call mode (.str "@cpu@_read_mem_" mode) + pc address)) + (set GRi address))) + ((fr400 (unit u-fr-load)) (fr450 (unit u-fr-load)) + (fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) + ) +) + +(conditional-load-non-gr-u cldbfu UQI OP_63 OPE4_0 FRint "Load byte float, update") +(conditional-load-non-gr-u cldhfu UHI OP_63 OPE4_1 FRint "Load half float, update") +(conditional-load-non-gr-u cldfu SI OP_63 OPE4_2 FRint "Load word float, update") + + +(dni clddu + "Load double word, update" + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) + (FR400-MAJOR I-2) (FR450-MAJOR I-2) CONDITIONAL) + "clddu$pack @($GRi,$GRj),$GRdoublek,$CCi,$cond" + (+ pack GRdoublek OP_62 GRi CCi cond OPE4_1 GRj) + (if (eq CCi (or cond 2)) + (sequence ((WI address)) + (load-double-semantics 0 DI GR address GRj) + (if (ne (index-of GRi) (index-of GRdoublek)) + (set GRi address)))) + ((fr400 (unit u-gr-load)) (fr450 (unit u-gr-load)) + (fr500 (unit u-gr-load)) (fr550 (unit u-gr-load))) +) + +(dni clddfu + "Load double float, update" + ((UNIT LOAD) (FR550-MAJOR I-3) (FR500-MAJOR I-2) + (FR400-MAJOR I-2) (FR450-MAJOR I-2) CONDITIONAL FR-ACCESS) + "clddfu$pack @($GRi,$GRj),$FRdoublek,$CCi,$cond" + (+ pack FRdoublek OP_63 GRi CCi cond OPE4_3 GRj) + (if (eq CCi (or cond 2)) + (sequence ((WI address)) + (load-double-semantics 1 DF FR address GRj) + (set GRi address))) + ((fr400 (unit u-fr-load)) (fr450 (unit u-fr-load)) + (fr500 (unit u-fr-load)) (fr550 (unit u-fr-load))) +) + +(dni cldqu + "conditional load quad integer and update index" + ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) CONDITIONAL) + "cldqu$pack @($GRi,$GRj),$GRk,$CCi,$cond" + (+ pack GRk OP_62 GRi CCi cond OPE4_2 GRj) + (if (eq CCi (or cond 2)) + (sequence ((WI address)) + (load-quad-semantics GR address GRj) + (if (ne (index-of GRi) (index-of GRk)) + (set GRi address)))) + ((fr500 (unit u-gr-load))) +) + +(define-pmacro (conditional-store name mode op ope regtype profile comment) + (dni name + (comment) + ((UNIT STORE) (FR550-MAJOR I-4) (FR500-MAJOR I-3) + (FR400-MAJOR I-3) (FR450-MAJOR I-3) CONDITIONAL) + (.str name "$pack $" regtype "k,@($GRi,$GRj),$CCi,$cond") + (+ pack (.sym regtype k) op GRi CCi cond ope GRj) + (if (eq CCi (or cond 2)) + (c-call VOID (.str "@cpu@_write_mem_" mode) + pc (add GRi GRj) (.sym regtype k))) + profile + ) +) + +(conditional-store cstb QI OP_64 OPE4_0 GR + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store unsigned byte") +(conditional-store csth HI OP_64 OPE4_1 GR + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store unsigned half") +(conditional-store cst SI OP_64 OPE4_2 GR + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store word") + +(conditional-store cstbf QI OP_66 OPE4_0 FRint + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store byte float") +(conditional-store csthf HI OP_66 OPE4_1 FRint + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store half float") +(conditional-store cstf SI OP_66 OPE4_2 FRint + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store word float") + +(define-pmacro (conditional-store-double + name mode op ope regtype attr profile comment) + (dni name + (comment) + ((UNIT STORE) (FR550-MAJOR I-4) (FR500-MAJOR I-3) + (FR400-MAJOR I-3) (FR450-MAJOR I-3) CONDITIONAL attr) + (.str name "$pack $" regtype "doublek,@($GRi,$GRj),$CCi,$cond") + (+ pack (.sym regtype doublek) op GRi CCi cond ope GRj) + (if (eq CCi (or cond 2)) + (sequence ((WI address)) + (store-double-semantics mode regtype address GRj))) + profile + ) +) + +(conditional-store-double cstd DI OP_64 OPE4_3 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store double word") +(conditional-store-double cstdf DF OP_66 OPE4_3 FR FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store double float") + +(dni cstq + "conditionally store quad word" + ((UNIT STORE) (FR500-MAJOR I-3) (MACH frv) CONDITIONAL) + "cstq$pack $GRk,@($GRi,$GRj),$CCi,$cond" + (+ pack GRk OP_65 GRi CCi cond OPE4_0 GRj) + (if (eq CCi (or cond 2)) + (sequence ((WI address)) + (store-quad-semantics GR address GRj))) + ((fr500 (unit u-gr-store))) +) + +(define-pmacro (conditional-store-u + name mode op ope regtype attr profile comment) + (dni name + (comment) + ((UNIT STORE) (FR550-MAJOR I-4) (FR500-MAJOR I-3) + (FR400-MAJOR I-3) (FR450-MAJOR I-3) CONDITIONAL attr) + (.str name "$pack $" regtype "k,@($GRi,$GRj),$CCi,$cond") + (+ pack (.sym regtype k) op GRi CCi cond ope GRj) + (if (eq CCi (or cond 2)) + (sequence ((WI address)) + (set address (add GRi GRj)) + (c-call VOID (.str "@cpu@_write_mem_" mode) + pc address (.sym regtype k)) + (set GRi address))) + profile + ) +) + +(conditional-store-u cstbu QI OP_67 OPE4_0 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store unsigned byte, update index") +(conditional-store-u csthu HI OP_67 OPE4_1 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store unsigned half, update index") +(conditional-store-u cstu SI OP_67 OPE4_2 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store word, update index") + +(conditional-store-u cstbfu QI OP_68 OPE4_0 FRint FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store byte float, update index") +(conditional-store-u csthfu HI OP_68 OPE4_1 FRint FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store half float, update index") +(conditional-store-u cstfu SI OP_68 OPE4_2 FRint FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store word float, update index") + +(define-pmacro (conditional-store-double-u + name mode op ope regtype attr profile comment) + (dni name + (comment) + ((UNIT STORE) (FR550-MAJOR I-4) (FR500-MAJOR I-3) + (FR400-MAJOR I-3) (FR450-MAJOR I-3) CONDITIONAL attr) + (.str name "$pack $" regtype "doublek,@($GRi,$GRj),$CCi,$cond") + (+ pack (.sym regtype doublek) op GRi CCi cond ope GRj) + (if (eq CCi (or cond 2)) + (sequence ((WI address)) + (store-double-semantics mode regtype address GRj) + (set GRi address))) + profile + ) +) + +(conditional-store-double-u cstdu DI OP_67 OPE4_3 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store double word, update index") +(conditional-store-double-u cstdfu DF OP_68 OPE4_3 FR FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store double float, update index") + +(define-pmacro (store-r-simm name mode op regtype attr profile comment) + (dni name + (comment) + ((UNIT STORE) (FR550-MAJOR I-4) (FR500-MAJOR I-3) + (FR400-MAJOR I-3) (FR450-MAJOR I-3) attr) + (.str name "$pack $" regtype "k,@($GRi,$d12)") + (+ pack (.sym regtype k) op GRi d12) + (c-call VOID (.str "@cpu@_write_mem_" mode) + pc (add GRi d12) (.sym regtype k)) + profile + ) +) + +(store-r-simm stbi QI OP_50 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store unsigned byte") +(store-r-simm sthi HI OP_51 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store unsigned half") +(store-r-simm sti SI OP_52 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store word") + +(store-r-simm stbfi QI OP_4E FRint FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store byte float") +(store-r-simm sthfi HI OP_4F FRint FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store half float") +(store-r-simm stfi SI OP_55 FRint FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store word float") + +(define-pmacro (store-double-r-simm name mode op regtype attr profile comment) + (dni name + (comment) + ((UNIT STORE) (FR550-MAJOR I-4) (FR500-MAJOR I-3) + (FR400-MAJOR I-3) (FR450-MAJOR I-3) attr) + (.str name "$pack $" regtype "doublek,@($GRi,$d12)") + (+ pack (.sym regtype doublek) op GRi d12) + (sequence ((WI address)) + (store-double-semantics mode regtype address d12)) + profile + ) +) + +(store-double-r-simm stdi DI OP_53 GR NA + ((fr400 (unit u-gr-store)) (fr450 (unit u-gr-store)) + (fr500 (unit u-gr-store)) (fr550 (unit u-gr-store))) + "Store double word") +(store-double-r-simm stdfi DF OP_56 FR FR-ACCESS + ((fr400 (unit u-fr-store)) (fr450 (unit u-fr-store)) + (fr500 (unit u-fr-store)) (fr550 (unit u-fr-store))) + "Store double float") + +(define-pmacro (store-quad-r-simm name op regtype attr profile comment) + (dni name + (comment) + ((UNIT STORE) (FR500-MAJOR I-3) (MACH frv) attr) + (.str name "$pack $" regtype "k,@($GRi,$d12)") + (+ pack (.sym regtype k) op GRi d12) + (sequence ((WI address)) + (store-quad-semantics regtype address d12)) + profile + ) +) + +(store-quad-r-simm stqi OP_54 GR NA ((fr500 (unit u-gr-store))) + "Store quad word") +(store-quad-r-simm stqfi OP_57 FRint FR-ACCESS () + "Store quad float") + +(define-pmacro (swap-semantics base offset arg) + (sequence ((WI tmp) (WI address)) + (set tmp arg) + (set address (add base offset)) + (c-call VOID "@cpu@_check_swap_address" address) + (set arg (c-call WI "@cpu@_read_mem_WI" pc address)) + (c-call VOID "@cpu@_write_mem_WI" pc address tmp)) +) + +(dni swap + "Swap contents of memory with GR" + ((UNIT C) (FR500-MAJOR C-2) (FR550-MAJOR C-2) + (FR400-MAJOR C-2) (FR450-MAJOR C-2)) + "swap$pack @($GRi,$GRj),$GRk" + (+ pack GRk OP_03 GRi OPE1_05 GRj) + (swap-semantics GRi GRj GRk) + ((fr400 (unit u-swap)) (fr450 (unit u-swap)) + (fr500 (unit u-swap)) (fr550 (unit u-swap))) +) + +(dni "swapi" + "Swap contents of memory with GR" + ((UNIT C) (FR500-MAJOR C-2) (FR550-MAJOR C-2) + (FR400-MAJOR C-2) (FR450-MAJOR C-2)) + ("swapi$pack @($GRi,$d12),$GRk") + (+ pack GRk OP_4D GRi d12) + (swap-semantics GRi d12 GRk) + ((fr400 (unit u-swap)) (fr450 (unit u-swap)) + (fr500 (unit u-swap)) (fr550 (unit u-swap))) +) + +(dni cswap + "Conditionally swap contents of memory with GR" + ((UNIT C) (FR500-MAJOR C-2) (FR550-MAJOR C-2) + (FR400-MAJOR C-2) (FR450-MAJOR C-2) CONDITIONAL) + "cswap$pack @($GRi,$GRj),$GRk,$CCi,$cond" + (+ pack GRk OP_65 GRi CCi cond OPE4_2 GRj) + (if (eq CCi (or cond 2)) + (swap-semantics GRi GRj GRk)) + ((fr400 (unit u-swap)) (fr450 (unit u-swap)) + (fr500 (unit u-swap)) (fr550 (unit u-swap))) +) + +(define-pmacro (register-transfer + name op ope reg_src reg_targ pipe attrs profile comment) + (dni name + (comment) + (.splice (UNIT pipe) (.unsplice attrs)) + (.str name "$pack $" reg_src ",$" reg_targ) + (+ pack reg_targ op (rs-null) ope reg_src) + (set reg_targ reg_src) + profile + ) +) + +(register-transfer movgf OP_03 OPE1_15 + GRj FRintk I0 + ((FR500-MAJOR I-4) (FR550-MAJOR I-5) + (FR400-MAJOR I-4) (FR450-MAJOR I-4) FR-ACCESS) + ((fr400 (unit u-gr2fr)) (fr450 (unit u-gr2fr)) + (fr500 (unit u-gr2fr)) (fr550 (unit u-gr2fr))) + "transfer gr to fr") +(register-transfer movfg OP_03 OPE1_0D + FRintk GRj I0 + ((FR500-MAJOR I-4) (FR550-MAJOR I-5) + (FR400-MAJOR I-4) (FR450-MAJOR I-4) FR-ACCESS) + ((fr400 (unit u-fr2gr)) (fr450 (unit u-fr2gr)) + (fr500 (unit u-fr2gr)) (fr550 (unit u-fr2gr))) + "transfer fr to gr") + +(define-pmacro (nextreg hw r offset) (reg hw (add (index-of r) offset))) + +(define-pmacro (register-transfer-double-from-gr-semantics cond) + (if cond + (if (eq (index-of GRj) 0) + (sequence () + (set FRintk 0) + (set (nextreg h-fr_int FRintk 1) 0)) + (sequence () + (set FRintk GRj) + (set (nextreg h-fr_int FRintk 1) (nextreg h-gr GRj 1))))) +) + +(dni movgfd + "move GR for FR double" + ((UNIT I0) (FR500-MAJOR I-4) (FR550-MAJOR I-5) + (FR400-MAJOR I-4) (FR450-MAJOR I-4) FR-ACCESS) + "movgfd$pack $GRj,$FRintk" + (+ pack FRintk OP_03 (rs-null) OPE1_16 GRj) + (register-transfer-double-from-gr-semantics 1) + ; TODO -- doesn't handle second register in the pair + ((fr400 (unit u-gr2fr)) (fr450 (unit u-gr2fr)) + (fr500 (unit u-gr2fr)) (fr550 (unit u-gr2fr))) +) + +(define-pmacro (register-transfer-double-to-gr-semantics cond) + (if (andif (ne (index-of GRj) 0) cond) + (sequence () + (set GRj FRintk) + (set (nextreg h-gr GRj 1) (nextreg h-fr_int FRintk 1)))) +) + +(dni movfgd + "move FR for GR double" + ((UNIT I0) (FR500-MAJOR I-4) (FR550-MAJOR I-5) + (FR400-MAJOR I-4) (FR450-MAJOR I-4) FR-ACCESS) + "movfgd$pack $FRintk,$GRj" + (+ pack FRintk OP_03 (rs-null) OPE1_0E GRj) + (register-transfer-double-to-gr-semantics 1) + ; TODO -- doesn't handle second register in the pair + ((fr400 (unit u-fr2gr)) (fr450 (unit u-fr2gr)) + (fr500 (unit u-fr2gr)) (fr550 (unit u-fr2gr))) +) + +(dni movgfq + "move GR for FR quad" + ((UNIT I0) (FR500-MAJOR I-4) (MACH frv) FR-ACCESS) + "movgfq$pack $GRj,$FRintk" + (+ pack FRintk OP_03 (rs-null) OPE1_17 GRj) + (if (eq (index-of GRj) 0) + (sequence () + (set FRintk 0) + (set (reg h-fr_int (add (index-of FRintk) 1)) 0) + (set (reg h-fr_int (add (index-of FRintk) 2)) 0) + (set (reg h-fr_int (add (index-of FRintk) 3)) 0)) + (sequence () + (set FRintk GRj) + (set (reg h-fr_int (add (index-of FRintk) 1)) + (reg h-gr (add (index-of GRj) 1))) + (set (reg h-fr_int (add (index-of FRintk) 2)) + (reg h-gr (add (index-of GRj) 2))) + (set (reg h-fr_int (add (index-of FRintk) 3)) + (reg h-gr (add (index-of GRj) 3))))) + () +) + +(dni movfgq + "move FR for GR quad" + ((UNIT I0) (FR500-MAJOR I-4) (MACH frv) FR-ACCESS) + "movfgq$pack $FRintk,$GRj" + (+ pack FRintk OP_03 (rs-null) OPE1_0F GRj) + (if (ne (index-of GRj) 0) + (sequence () + (set GRj FRintk) + (set (reg h-gr (add (index-of GRj) 1)) + (reg h-fr_int (add (index-of FRintk) 1))) + (set (reg h-gr (add (index-of GRj) 2)) + (reg h-fr_int (add (index-of FRintk) 2))) + (set (reg h-gr (add (index-of GRj) 3)) + (reg h-fr_int (add (index-of FRintk) 3))))) + () +) + +(define-pmacro (conditional-register-transfer + name op ope reg_src reg_targ pipe attrs profile comment) + (dni name + (comment) + (.splice (UNIT pipe) CONDITIONAL FR-ACCESS (.unsplice attrs)) + (.str name "$pack $" reg_src ",$" reg_targ ",$CCi,$cond") + (+ pack reg_targ op (rs-null) CCi cond ope reg_src) + (if (eq CCi (or cond 2)) + (set reg_targ reg_src)) + profile + ) +) + +(conditional-register-transfer cmovgf OP_69 OPE4_0 GRj FRintk I0 + ((FR500-MAJOR I-4) (FR550-MAJOR I-5) + (FR400-MAJOR I-4) (FR450-MAJOR I-4)) + ((fr400 (unit u-gr2fr)) (fr450 (unit u-gr2fr)) + (fr500 (unit u-gr2fr)) (fr550 (unit u-gr2fr))) + "transfer gr to fr") +(conditional-register-transfer cmovfg OP_69 OPE4_2 FRintk GRj I0 + ((FR500-MAJOR I-4) (FR550-MAJOR I-5) + (FR400-MAJOR I-4) (FR450-MAJOR I-4)) + ((fr400 (unit u-fr2gr)) (fr450 (unit u-fr2gr)) + (fr500 (unit u-fr2gr)) (fr550 (unit u-fr2gr))) + "transfer fr to gr") + + +(dni cmovgfd + "Conditional move GR to FR double" + ((UNIT I0) (FR500-MAJOR I-4) (FR550-MAJOR I-5) + (FR400-MAJOR I-4) (FR450-MAJOR I-4) CONDITIONAL FR-ACCESS) + "cmovgfd$pack $GRj,$FRintk,$CCi,$cond" + (+ pack FRintk OP_69 (rs-null) CCi cond OPE4_1 GRj) + (register-transfer-double-from-gr-semantics (eq CCi (or cond 2))) + ; TODO -- doesn't handle extra registers in double + ((fr400 (unit u-gr2fr)) (fr450 (unit u-gr2fr)) + (fr500 (unit u-gr2fr)) (fr550 (unit u-gr2fr))) +) + +(dni cmovfgd + "Conditional move FR to GR double" + ((UNIT I0) (FR500-MAJOR I-4) (FR550-MAJOR I-5) + (FR400-MAJOR I-4) (FR450-MAJOR I-4) CONDITIONAL FR-ACCESS) + "cmovfgd$pack $FRintk,$GRj,$CCi,$cond" + (+ pack FRintk OP_69 (rs-null) CCi cond OPE4_3 GRj) + (register-transfer-double-to-gr-semantics (eq CCi (or cond 2))) + ; TODO -- doesn't handle second register in the pair + ((fr400 (unit u-fr2gr)) (fr450 (unit u-fr2gr)) + (fr500 (unit u-fr2gr)) (fr550 (unit u-fr2gr))) +) + +(define-pmacro (register-transfer-spr + name op ope reg_src reg_targ unitname comment) + (dni name + (comment) + ((UNIT C) (FR500-MAJOR C-2) (FR550-MAJOR C-2) + (FR400-MAJOR C-2) (FR450-MAJOR C-2)) + (.str name "$pack $" reg_src ",$" reg_targ) + (+ pack reg_targ op ope reg_src) + (set reg_targ reg_src) + ((fr400 (unit unitname)) (fr450 (unit unitname)) + (fr500 (unit unitname)) (fr550 (unit unitname))) + ) +) + +(register-transfer-spr movgs OP_03 OPE1_06 GRj spr u-gr2spr "transfer gr->spr") +(register-transfer-spr movsg OP_03 OPE1_07 spr GRj u-spr2gr "transfer spr->gr") + +; Integer Branch Conditions +(define-pmacro (Inev cc) (const BI 0)) +(define-pmacro (Ira cc) (const BI 1)) +(define-pmacro (Ieq cc) ( zbit cc)) +(define-pmacro (Ine cc) (not (zbit cc))) +(define-pmacro (Ile cc) ( orif (zbit cc) (xor (nbit cc) (vbit cc)))) +(define-pmacro (Igt cc) (not (orif (zbit cc) (xor (nbit cc) (vbit cc))))) +(define-pmacro (Ilt cc) ( xor (nbit cc) (vbit cc))) +(define-pmacro (Ige cc) (not (xor (nbit cc) (vbit cc)))) +(define-pmacro (Ils cc) ( orif (cbit cc) (zbit cc))) +(define-pmacro (Ihi cc) (not (orif (cbit cc) (zbit cc)))) +(define-pmacro (Ic cc) ( cbit cc)) +(define-pmacro (Inc cc) (not (cbit cc))) +(define-pmacro (In cc) ( nbit cc)) +(define-pmacro (Ip cc) (not (nbit cc))) +(define-pmacro (Iv cc) ( vbit cc)) +(define-pmacro (Inv cc) (not (vbit cc))) + +; Float Branch Conditions +(define-pmacro (Fnev cc) (const BI 0)) +(define-pmacro (Fra cc) (const BI 1)) +(define-pmacro (Fne cc) (orif (lbit cc) (orif (gbit cc) (ubit cc)))) +(define-pmacro (Feq cc) (ebit cc)) +(define-pmacro (Flg cc) (orif (lbit cc) (gbit cc))) +(define-pmacro (Fue cc) (orif (ebit cc) (ubit cc))) +(define-pmacro (Ful cc) (orif (lbit cc) (ubit cc))) +(define-pmacro (Fge cc) (orif (ebit cc) (gbit cc))) +(define-pmacro (Flt cc) (lbit cc)) +(define-pmacro (Fuge cc) (orif (ebit cc) (orif (gbit cc) (ubit cc)))) +(define-pmacro (Fug cc) (orif (gbit cc) (ubit cc))) +(define-pmacro (Fle cc) (orif (ebit cc) (lbit cc))) +(define-pmacro (Fgt cc) (gbit cc)) +(define-pmacro (Fule cc) (orif (ebit cc) (orif (lbit cc) (ubit cc)))) +(define-pmacro (Fu cc) (ubit cc)) +(define-pmacro (Fo cc) (orif (ebit cc) (orif (lbit cc) (gbit cc)))) + +(define-pmacro (conditional-branch-i prefix cc op cond comment) + (dni (.sym prefix cc) + (comment) + ((UNIT B01) (FR500-MAJOR B-1) (FR550-MAJOR B-1) + (FR400-MAJOR B-1) (FR450-MAJOR B-1)) + (.str (.sym prefix cc) "$pack $ICCi_2,$hint,$label16") + (+ pack (.sym ICC_ cc) ICCi_2 op hint label16) + (sequence () + (c-call VOID "@cpu@_model_branch" label16 hint) + (if (cond ICCi_2) + (set pc label16))) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) + ) +) + +(dni bra + "integer branch equal" + ((UNIT B01) (FR500-MAJOR B-1) (FR550-MAJOR B-1) + (FR400-MAJOR B-1) (FR450-MAJOR B-1)) + "bra$pack $hint_taken$label16" + (+ pack ICC_ra (ICCi_2-null) OP_06 hint_taken label16) + (sequence () + (c-call VOID "@cpu@_model_branch" label16 hint_taken) + (set pc label16)) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(dni bno + "integer branch never" + ((UNIT B01) (FR500-MAJOR B-1) (FR550-MAJOR B-1) + (FR400-MAJOR B-1) (FR450-MAJOR B-1)) + "bno$pack$hint_not_taken" + (+ pack ICC_nev (ICCi_2-null) OP_06 hint_not_taken (label16-null)) + (c-call VOID "@cpu@_model_branch" label16 hint_not_taken) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(conditional-branch-i b eq OP_06 Ieq "integer branch equal") +(conditional-branch-i b ne OP_06 Ine "integer branch not equal") +(conditional-branch-i b le OP_06 Ile "integer branch less or equal") +(conditional-branch-i b gt OP_06 Igt "integer branch greater") +(conditional-branch-i b lt OP_06 Ilt "integer branch less") +(conditional-branch-i b ge OP_06 Ige "integer branch greater or equal") +(conditional-branch-i b ls OP_06 Ils "integer branch less or equal unsigned") +(conditional-branch-i b hi OP_06 Ihi "integer branch greater unsigned") +(conditional-branch-i b c OP_06 Ic "integer branch carry set") +(conditional-branch-i b nc OP_06 Inc "integer branch carry clear") +(conditional-branch-i b n OP_06 In "integer branch negative") +(conditional-branch-i b p OP_06 Ip "integer branch positive") +(conditional-branch-i b v OP_06 Iv "integer branch overflow set") +(conditional-branch-i b nv OP_06 Inv "integer branch overflow clear") + +(define-pmacro (conditional-branch-f prefix cc op cond comment) + (dni (.sym prefix cc) + (comment) + ((UNIT B01) (FR500-MAJOR B-1) (FR550-MAJOR B-1) + (FR400-MAJOR B-1) (FR450-MAJOR B-1) FR-ACCESS) + (.str (.sym prefix cc) "$pack $FCCi_2,$hint,$label16") + (+ pack (.sym FCC_ cc) FCCi_2 op hint label16) + (sequence () + (c-call VOID "@cpu@_model_branch" label16 hint) + (if (cond FCCi_2) (set pc label16))) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) + ) +) + +(dni fbra + "float branch equal" + ((UNIT B01) (FR500-MAJOR B-1) (FR550-MAJOR B-1) + (FR400-MAJOR B-1) (FR450-MAJOR B-1) FR-ACCESS) + "fbra$pack $hint_taken$label16" + (+ pack FCC_ra (FCCi_2-null) OP_07 hint_taken label16) + (sequence () + (c-call VOID "@cpu@_model_branch" label16 hint_taken) + (set pc label16)) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(dni fbno + "float branch never" + ((UNIT B01) (FR500-MAJOR B-1) (FR550-MAJOR B-1) + (FR400-MAJOR B-1) (FR450-MAJOR B-1) FR-ACCESS) + "fbno$pack$hint_not_taken" + (+ pack FCC_nev (FCCi_2-null) OP_07 hint_not_taken (label16-null)) + (c-call VOID "@cpu@_model_branch" label16 hint_not_taken) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(conditional-branch-f fb ne OP_07 Fne "float branch not equal") +(conditional-branch-f fb eq OP_07 Feq "float branch equal") +(conditional-branch-f fb lg OP_07 Flg "float branch less or greater") +(conditional-branch-f fb ue OP_07 Fue "float branch unordered or equal") +(conditional-branch-f fb ul OP_07 Ful "float branch unordered or less") +(conditional-branch-f fb ge OP_07 Fge "float branch greater or equal") +(conditional-branch-f fb lt OP_07 Flt "float branch less") +(conditional-branch-f fb uge OP_07 Fuge "float branch unordered, greater,equal") +(conditional-branch-f fb ug OP_07 Fug "float branch unordered or greater") +(conditional-branch-f fb le OP_07 Fle "float branch less or equal") +(conditional-branch-f fb gt OP_07 Fgt "float branch greater") +(conditional-branch-f fb ule OP_07 Fule "float branch unordered, less or equal") +(conditional-branch-f fb u OP_07 Fu "float branch unordered") +(conditional-branch-f fb o OP_07 Fo "float branch ordered") + +(define-pmacro (ctrlr-branch-semantics cond ccond) + (sequence ((SI tmp)) + (set tmp (sub (spr-lcr) 1)) + (set (spr-lcr) tmp) + (if cond + (if (eq ccond 0) + (if (ne tmp 0) + (set pc (spr-lr))) + (if (eq tmp 0) + (set pc (spr-lr)))))) +) + +(dni bctrlr + "LCR conditional branch to lr" + ((UNIT B0) (FR500-MAJOR B-2) (FR550-MAJOR B-2) + (FR400-MAJOR B-2) (FR450-MAJOR B-2)) + ("bctrlr$pack $ccond,$hint") + (+ pack (cond-null) (ICCi_2-null) OP_0E hint OPE3_01 ccond (s12-null)) + (sequence () + (c-call VOID "@cpu@_model_branch" (spr-lr) hint) + (ctrlr-branch-semantics (const BI 1) ccond)) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(define-pmacro (conditional-branch-cclr prefix cc i-f op ope cond attr comment) + (dni (.sym prefix cc lr) + (comment) + ((UNIT B01) (FR500-MAJOR B-3) (FR550-MAJOR B-3) + (FR400-MAJOR B-3) (FR450-MAJOR B-3) attr) + (.str (.sym prefix cc lr) "$pack $" i-f "CCi_2,$hint") + (+ pack (.sym i-f CC_ cc) (.sym i-f CCi_2) op hint ope + (ccond-null) (s12-null)) + (sequence () + (c-call VOID "@cpu@_model_branch" (spr-lr) hint) + (if (cond (.sym i-f CCi_2)) (set pc (spr-lr)))) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) + ) +) + +(dni bralr + "integer cclr branch always" + ((UNIT B01) (FR500-MAJOR B-3) (FR550-MAJOR B-3) + (FR400-MAJOR B-3) (FR450-MAJOR B-3)) + "bralr$pack$hint_taken" + (+ pack ICC_ra (ICCi_2-null) OP_0E hint_taken OPE3_02 (ccond-null) (s12-null)) + (sequence () + (c-call VOID "@cpu@_model_branch" (spr-lr) hint_taken) + (set pc (spr-lr))) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(dni bnolr + "integer cclr branch never" + ((UNIT B01) (FR500-MAJOR B-3) (FR550-MAJOR B-3) + (FR400-MAJOR B-3) (FR450-MAJOR B-3)) + "bnolr$pack$hint_not_taken" + (+ pack ICC_nev (ICCi_2-null) OP_0E hint_not_taken OPE3_02 (ccond-null) (s12-null)) + (c-call VOID "@cpu@_model_branch" (spr-lr) hint_not_taken) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(conditional-branch-cclr b eq I OP_0E OPE3_02 Ieq NA "integer cclr branch equal") +(conditional-branch-cclr b ne I OP_0E OPE3_02 Ine NA "integer cclr branch not equal") +(conditional-branch-cclr b le I OP_0E OPE3_02 Ile NA "integer cclr branch less or equal") +(conditional-branch-cclr b gt I OP_0E OPE3_02 Igt NA "integer cclr branch greater") +(conditional-branch-cclr b lt I OP_0E OPE3_02 Ilt NA "integer cclr branch less") +(conditional-branch-cclr b ge I OP_0E OPE3_02 Ige NA "integer cclr branch greater or equal") +(conditional-branch-cclr b ls I OP_0E OPE3_02 Ils NA "integer cclr branch less or equal unsigned") +(conditional-branch-cclr b hi I OP_0E OPE3_02 Ihi NA "integer cclr branch greater unsigned") +(conditional-branch-cclr b c I OP_0E OPE3_02 Ic NA "integer cclr branch carry set") +(conditional-branch-cclr b nc I OP_0E OPE3_02 Inc NA "integer cclr branch carry clear") +(conditional-branch-cclr b n I OP_0E OPE3_02 In NA "integer cclr branch negative") +(conditional-branch-cclr b p I OP_0E OPE3_02 Ip NA "integer cclr branch positive") +(conditional-branch-cclr b v I OP_0E OPE3_02 Iv NA "integer cclr branch overflow set") +(conditional-branch-cclr b nv I OP_0E OPE3_02 Inv NA "integer cclr branch overflow clear") + +(dni fbralr + "float cclr branch always" + ((UNIT B01) (FR500-MAJOR B-3) (FR550-MAJOR B-3) + (FR400-MAJOR B-3) (FR450-MAJOR B-3) FR-ACCESS) + "fbralr$pack$hint_taken" + (+ pack FCC_ra (FCCi_2-null) OP_0E hint_taken OPE3_06 (ccond-null) (s12-null)) + (sequence () + (c-call VOID "@cpu@_model_branch" (spr-lr) hint_taken) + (set pc (spr-lr))) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(dni fbnolr + "float cclr branch never" + ((UNIT B01) (FR500-MAJOR B-3) (FR550-MAJOR B-3) + (FR400-MAJOR B-3) (FR450-MAJOR B-3) FR-ACCESS) + "fbnolr$pack$hint_not_taken" + (+ pack FCC_nev (FCCi_2-null) OP_0E hint_not_taken OPE3_06 (ccond-null) (s12-null)) + (c-call VOID "@cpu@_model_branch" (spr-lr) hint_not_taken) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(conditional-branch-cclr fb eq F OP_0E OPE3_06 Feq FR-ACCESS "float cclr branch equal") +(conditional-branch-cclr fb ne F OP_0E OPE3_06 Fne FR-ACCESS "float cclr branch not equal") +(conditional-branch-cclr fb lg F OP_0E OPE3_06 Flg FR-ACCESS "float branch less or greater") +(conditional-branch-cclr fb ue F OP_0E OPE3_06 Fue FR-ACCESS "float branch unordered or equal") +(conditional-branch-cclr fb ul F OP_0E OPE3_06 Ful FR-ACCESS "float branch unordered or less") +(conditional-branch-cclr fb ge F OP_0E OPE3_06 Fge FR-ACCESS "float branch greater or equal") +(conditional-branch-cclr fb lt F OP_0E OPE3_06 Flt FR-ACCESS "float branch less") +(conditional-branch-cclr fb uge F OP_0E OPE3_06 Fuge FR-ACCESS "float branch unordered, greater, equal") +(conditional-branch-cclr fb ug F OP_0E OPE3_06 Fug FR-ACCESS "float branch unordered or greater") +(conditional-branch-cclr fb le F OP_0E OPE3_06 Fle FR-ACCESS "float branch less or equal") +(conditional-branch-cclr fb gt F OP_0E OPE3_06 Fgt FR-ACCESS "float branch greater") +(conditional-branch-cclr fb ule F OP_0E OPE3_06 Fule FR-ACCESS "float branch unordered, less or equal") +(conditional-branch-cclr fb u F OP_0E OPE3_06 Fu FR-ACCESS "float branch unordered") +(conditional-branch-cclr fb o F OP_0E OPE3_06 Fo FR-ACCESS "float branch ordered") + +(define-pmacro (conditional-branch-ctrlr prefix cc i-f op ope cond attr comment) + (dni (.sym prefix cc lr) + (comment) + ((UNIT B0) (FR500-MAJOR B-2) (FR550-MAJOR B-2) + (FR400-MAJOR B-2) (FR450-MAJOR B-2) attr) + (.str (.sym prefix cc lr) "$pack $" i-f "CCi_2,$ccond,$hint") + (+ pack (.sym i-f CC_ cc) (.sym i-f CCi_2) op hint ope ccond (s12-null)) + (sequence () + (c-call VOID "@cpu@_model_branch" (spr-lr) hint) + (ctrlr-branch-semantics (cond (.sym i-f CCi_2)) ccond)) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) + ) +) + +(dni bcralr + "integer ctrlr branch always" + ((UNIT B0) (FR500-MAJOR B-2) (FR550-MAJOR B-2) + (FR400-MAJOR B-2) (FR450-MAJOR B-2)) + "bcralr$pack $ccond$hint_taken" + (+ pack ICC_ra (ICCi_2-null) OP_0E hint_taken OPE3_03 ccond (s12-null)) + (sequence () + (c-call VOID "@cpu@_model_branch" (spr-lr) hint_taken) + (ctrlr-branch-semantics (const BI 1) ccond)) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(dni bcnolr + "integer ctrlr branch never" + ((UNIT B0) (FR500-MAJOR B-2) (FR550-MAJOR B-2) + (FR400-MAJOR B-2) (FR450-MAJOR B-2)) + "bcnolr$pack$hint_not_taken" + (+ pack ICC_nev (ICCi_2-null) OP_0E hint_not_taken OPE3_03 (ccond-null) (s12-null)) + (sequence () + (c-call VOID "@cpu@_model_branch" (spr-lr) hint_not_taken) + (ctrlr-branch-semantics (const BI 0) ccond)) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(conditional-branch-ctrlr bc eq I OP_0E OPE3_03 Ieq NA "integer ctrlr branch equal") +(conditional-branch-ctrlr bc ne I OP_0E OPE3_03 Ine NA "integer ctrlr branch not equal") +(conditional-branch-ctrlr bc le I OP_0E OPE3_03 Ile NA "integer ctrlr branch less equal") +(conditional-branch-ctrlr bc gt I OP_0E OPE3_03 Igt NA "integer ctrlr branch greater") +(conditional-branch-ctrlr bc lt I OP_0E OPE3_03 Ilt NA "integer ctrlr branch less") +(conditional-branch-ctrlr bc ge I OP_0E OPE3_03 Ige NA "integer ctrlr branch greater equal") +(conditional-branch-ctrlr bc ls I OP_0E OPE3_03 Ils NA "integer ctrlr branch less equal unsigned") +(conditional-branch-ctrlr bc hi I OP_0E OPE3_03 Ihi NA "integer ctrlr branch greater unsigned") +(conditional-branch-ctrlr bc c I OP_0E OPE3_03 Ic NA "integer ctrlr branch carry set") +(conditional-branch-ctrlr bc nc I OP_0E OPE3_03 Inc NA "integer ctrlr branch carry clear") +(conditional-branch-ctrlr bc n I OP_0E OPE3_03 In NA "integer ctrlr branch negative") +(conditional-branch-ctrlr bc p I OP_0E OPE3_03 Ip NA "integer ctrlr branch positive") +(conditional-branch-ctrlr bc v I OP_0E OPE3_03 Iv NA "integer ctrlr branch overflow set") +(conditional-branch-ctrlr bc nv I OP_0E OPE3_03 Inv NA "integer ctrlr branch overflow clear") + +(dni fcbralr + "float ctrlr branch always" + ((UNIT B0) (FR500-MAJOR B-2) (FR550-MAJOR B-2) + (FR400-MAJOR B-2) (FR450-MAJOR B-2) FR-ACCESS) + "fcbralr$pack $ccond$hint_taken" + (+ pack FCC_ra (FCCi_2-null) OP_0E hint_taken OPE3_07 ccond (s12-null)) + (sequence () + (c-call VOID "@cpu@_model_branch" (spr-lr) hint_taken) + (ctrlr-branch-semantics (const BI 1) ccond)) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(dni fcbnolr + "float ctrlr branch never" + ((UNIT B0) (FR500-MAJOR B-2) (FR550-MAJOR B-2) + (FR400-MAJOR B-2) (FR450-MAJOR B-2) FR-ACCESS) + "fcbnolr$pack$hint_not_taken" + (+ pack FCC_nev (FCCi_2-null) OP_0E hint_not_taken OPE3_07 (ccond-null) (s12-null)) + (sequence () + (c-call VOID "@cpu@_model_branch" (spr-lr) hint_not_taken) + (ctrlr-branch-semantics (const BI 0) ccond)) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(conditional-branch-ctrlr fcb eq F OP_0E OPE3_07 Feq FR-ACCESS "float cclr branch equal") +(conditional-branch-ctrlr fcb ne F OP_0E OPE3_07 Fne FR-ACCESS "float cclr branch not equal") +(conditional-branch-ctrlr fcb lg F OP_0E OPE3_07 Flg FR-ACCESS "float branch less or greater") +(conditional-branch-ctrlr fcb ue F OP_0E OPE3_07 Fue FR-ACCESS "float branch unordered or equal") +(conditional-branch-ctrlr fcb ul F OP_0E OPE3_07 Ful FR-ACCESS "float branch unordered or less") +(conditional-branch-ctrlr fcb ge F OP_0E OPE3_07 Fge FR-ACCESS "float branch greater or equal") +(conditional-branch-ctrlr fcb lt F OP_0E OPE3_07 Flt FR-ACCESS "float branch less") +(conditional-branch-ctrlr fcb uge F OP_0E OPE3_07 Fuge FR-ACCESS "float branch unordered, greater, equal") +(conditional-branch-ctrlr fcb ug F OP_0E OPE3_07 Fug FR-ACCESS "float branch unordered or greater") +(conditional-branch-ctrlr fcb le F OP_0E OPE3_07 Fle FR-ACCESS "float branch less or equal") +(conditional-branch-ctrlr fcb gt F OP_0E OPE3_07 Fgt FR-ACCESS "float branch greater") +(conditional-branch-ctrlr fcb ule F OP_0E OPE3_07 Fule FR-ACCESS "float branch unordered, less or equal") +(conditional-branch-ctrlr fcb u F OP_0E OPE3_07 Fu FR-ACCESS "float branch unordered") +(conditional-branch-ctrlr fcb o F OP_0E OPE3_07 Fo FR-ACCESS "float branch ordered") + +(define-pmacro (jump-and-link-semantics base offset LI) + (sequence () + (if (eq LI 1) + (c-call VOID "@cpu@_set_write_next_vliw_addr_to_LR" 1)) + ; Target address gets aligned here + (set pc (and (add base offset) #xfffffffc)) + (c-call VOID "@cpu@_model_branch" pc #x2)) ; hint branch taken +) + +(dni jmpl + "jump and link" + ((UNIT I0) (FR500-MAJOR I-5) (FR550-MAJOR I-6) + (FR400-MAJOR I-5) (FR450-MAJOR I-5)) + "jmpl$pack @($GRi,$GRj)" + (+ pack (misc-null-1) (LI-off) OP_0C GRi (misc-null-2) GRj) + (jump-and-link-semantics GRi GRj LI) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(dann callann "call annotation" SI "call_annotation" "at") + +(dni calll + "call and link" + ((UNIT I0) (FR500-MAJOR I-5) (FR550-MAJOR I-6) + (FR400-MAJOR I-5) (FR450-MAJOR I-5)) + "calll$pack $callann($GRi,$GRj)" + (+ pack (misc-null-1) (LI-on) OP_0C GRi (misc-null-2) GRj) + (jump-and-link-semantics GRi GRj LI) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(dni jmpil + "jump immediate and link" + ((UNIT I0) (FR500-MAJOR I-5) (FR550-MAJOR I-6) + (FR400-MAJOR I-5) (FR450-MAJOR I-5)) + "jmpil$pack @($GRi,$s12)" + (+ pack (misc-null-1) (LI-off) OP_0D GRi s12) + (jump-and-link-semantics GRi s12 LI) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(dni callil + "call immediate and link" + ((UNIT I0) (FR500-MAJOR I-5) (FR550-MAJOR I-6) + (FR400-MAJOR I-5) (FR450-MAJOR I-5)) + "callil$pack @($GRi,$s12)" + (+ pack (misc-null-1) (LI-on) OP_0D GRi s12) + (jump-and-link-semantics GRi s12 LI) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(dni call + "call and link" + ((UNIT B0) (FR500-MAJOR B-4) (FR550-MAJOR B-4) + (FR400-MAJOR B-4) (FR450-MAJOR B-4)) + "call$pack $label24" + (+ pack OP_0F label24) + (sequence () + (c-call VOID "@cpu@_set_write_next_vliw_addr_to_LR" 1) + (set pc label24) + (c-call VOID "@cpu@_model_branch" pc #x2)) ; hint branch taken + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(dni rett + "return from trap" + ((UNIT C) (FR500-MAJOR C-2) (FR550-MAJOR C-2) + (FR400-MAJOR C-2) (FR450-MAJOR C-2) PRIVILEGED) + "rett$pack $debug" + (+ pack (misc-null-1) debug OP_05 (rs-null) (s12-null)) + ; frv_rett handles operating vs user mode + (sequence () + (set pc (c-call UWI "frv_rett" pc debug)) + (c-call VOID "@cpu@_model_branch" pc #x2)) ; hint branch taken + () +) + +(dni rei + "run exception instruction" + ((UNIT C) (FR500-MAJOR C-1) (MACH frv) PRIVILEGED) + "rei$pack $eir" + (+ pack (rd-null) OP_37 eir (s12-null)) + (nop) ; for now + () +) + +(define-pmacro (trap-semantics cond base offset) + (if cond + (sequence () + ; This is defered to frv_itrap because for the breakpoint + ; case we want to change as little of the machine state as + ; possible. + ; + ; PCSR=PC + ; PSR.PS=PSR.S + ; PSR.ET=0 + ; if PSR.ESR==1 + ; SR0 through SR3=GR4 through GR7 + ; TBR.TT=0x80 + ((GRi + s12) & 0x7f) + ; PC=TBR + ; We still should indicate what is modified by this insn. + (clobber (spr-pcsr)) + (clobber psr_ps) + (clobber psr_et) + (clobber tbr_tt) + (if (ne psr_esr (const 0)) + (sequence () + (clobber (spr-sr0)) + (clobber (spr-sr1)) + (clobber (spr-sr2)) + (clobber (spr-sr3)))) + ; frv_itrap handles operating vs user mode + (c-call VOID "frv_itrap" pc base offset))) +) + +(define-pmacro (trap-r prefix cc i-f op ope cond attr comment) + (dni (.sym prefix cc) + (comment) + ((UNIT C) (FR500-MAJOR C-1) (FR550-MAJOR C-1) + (FR400-MAJOR C-1) (FR450-MAJOR C-1) attr) + (.str (.sym prefix cc) "$pack $" i-f "CCi_2,$GRi,$GRj") + (+ pack (.sym i-f CC_ cc) (.sym i-f CCi_2) op GRi (misc-null-3) ope GRj) + (trap-semantics (cond (.sym i-f CCi_2)) GRi GRj) + ((fr400 (unit u-trap)) (fr450 (unit u-trap)) + (fr500 (unit u-trap)) (fr550 (unit u-trap))) + ) +) + +(dni tra + "integer trap always" + ((UNIT C) (FR500-MAJOR C-1) (FR550-MAJOR C-1) + (FR400-MAJOR C-1) (FR450-MAJOR C-1)) + "tra$pack $GRi,$GRj" + (+ pack ICC_ra (ICCi_2-null) OP_04 GRi (misc-null-3) OPE4_0 GRj) + (trap-semantics (const BI 1) GRi GRj) + ((fr400 (unit u-trap)) (fr450 (unit u-trap)) + (fr500 (unit u-trap)) (fr550 (unit u-trap))) +) + +(dni tno + "integer trap never" + ((UNIT C) (FR500-MAJOR C-1) (FR550-MAJOR C-1) + (FR400-MAJOR C-1) (FR450-MAJOR C-1)) + "tno$pack" + (+ pack ICC_nev (ICCi_2-null) OP_04 (GRi-null) (misc-null-3) OPE4_0 (GRj-null)) + (trap-semantics (const BI 0) GRi GRj) + ((fr400 (unit u-trap)) (fr450 (unit u-trap)) + (fr500 (unit u-trap)) (fr550 (unit u-trap))) +) + +(trap-r t eq I OP_04 OPE4_0 Ieq NA "integer trap equal") +(trap-r t ne I OP_04 OPE4_0 Ine NA "integer trap not equal") +(trap-r t le I OP_04 OPE4_0 Ile NA "integer trap less or equal") +(trap-r t gt I OP_04 OPE4_0 Igt NA "integer trap greater") +(trap-r t lt I OP_04 OPE4_0 Ilt NA "integer trap less") +(trap-r t ge I OP_04 OPE4_0 Ige NA "integer trap greater or equal") +(trap-r t ls I OP_04 OPE4_0 Ils NA "integer trap less or equal unsigned") +(trap-r t hi I OP_04 OPE4_0 Ihi NA "integer trap greater unsigned") +(trap-r t c I OP_04 OPE4_0 Ic NA "integer trap carry set") +(trap-r t nc I OP_04 OPE4_0 Inc NA "integer trap carry clear") +(trap-r t n I OP_04 OPE4_0 In NA "integer trap negative") +(trap-r t p I OP_04 OPE4_0 Ip NA "integer trap positive") +(trap-r t v I OP_04 OPE4_0 Iv NA "integer trap overflow set") +(trap-r t nv I OP_04 OPE4_0 Inv NA "integer trap overflow clear") + +(dni ftra + "float trap always" + ((UNIT C) (FR500-MAJOR C-1) (FR550-MAJOR C-1) + (FR400-MAJOR C-1) (FR450-MAJOR C-1) FR-ACCESS) + "ftra$pack $GRi,$GRj" + (+ pack FCC_ra (FCCi_2-null) OP_04 GRi (misc-null-3) OPE4_1 GRj) + (trap-semantics (const BI 1) GRi GRj) + ((fr400 (unit u-trap)) (fr450 (unit u-trap)) + (fr500 (unit u-trap)) (fr550 (unit u-trap))) +) + +(dni ftno + "flost trap never" + ((UNIT C) (FR500-MAJOR C-1) (FR550-MAJOR C-1) + (FR400-MAJOR C-1) (FR450-MAJOR C-1) FR-ACCESS) + "ftno$pack" + (+ pack FCC_nev (FCCi_2-null) OP_04 (GRi-null) (misc-null-3) OPE4_1 (GRj-null)) + (trap-semantics (const BI 0) GRi GRj) + ((fr400 (unit u-trap)) (fr450 (unit u-trap)) + (fr500 (unit u-trap)) (fr550 (unit u-trap))) +) + +(trap-r ft ne F OP_04 OPE4_1 Fne FR-ACCESS "float trap not equal") +(trap-r ft eq F OP_04 OPE4_1 Feq FR-ACCESS "float trap equal") +(trap-r ft lg F OP_04 OPE4_1 Flg FR-ACCESS "float trap greater or less") +(trap-r ft ue F OP_04 OPE4_1 Fue FR-ACCESS "float trap unordered or equal") +(trap-r ft ul F OP_04 OPE4_1 Ful FR-ACCESS "float trap unordered or less") +(trap-r ft ge F OP_04 OPE4_1 Fge FR-ACCESS "float trap greater or equal") +(trap-r ft lt F OP_04 OPE4_1 Flt FR-ACCESS "float trap less") +(trap-r ft uge F OP_04 OPE4_1 Fuge FR-ACCESS "float trap unordered greater or equal") +(trap-r ft ug F OP_04 OPE4_1 Fug FR-ACCESS "float trap unordered or greater") +(trap-r ft le F OP_04 OPE4_1 Fle FR-ACCESS "float trap less or equal") +(trap-r ft gt F OP_04 OPE4_1 Fgt FR-ACCESS "float trap greater") +(trap-r ft ule F OP_04 OPE4_1 Fule FR-ACCESS "float trap unordered less or equal") +(trap-r ft u F OP_04 OPE4_1 Fu FR-ACCESS "float trap unordered") +(trap-r ft o F OP_04 OPE4_1 Fo FR-ACCESS "float trap ordered") + +(define-pmacro (trap-immed prefix cc i-f op cond attr comment) + (dni (.sym prefix cc) + (comment) + ((UNIT C) (FR500-MAJOR C-1) (FR550-MAJOR C-1) + (FR400-MAJOR C-1) (FR450-MAJOR C-1) attr) + (.str (.sym prefix cc) "$pack $" i-f "CCi_2,$GRi,$s12") + (+ pack (.sym i-f CC_ cc) (.sym i-f CCi_2) op GRi s12) + (trap-semantics (cond (.sym i-f CCi_2)) GRi s12) + ((fr400 (unit u-trap)) (fr450 (unit u-trap)) + (fr500 (unit u-trap)) (fr550 (unit u-trap))) + ) +) + +(dni tira + "integer trap always" + ((UNIT C) (FR500-MAJOR C-1) (FR550-MAJOR C-1) + (FR400-MAJOR C-1) (FR450-MAJOR C-1)) + "tira$pack $GRi,$s12" + (+ pack ICC_ra (ICCi_2-null) OP_1C GRi s12) + (trap-semantics (const BI 1) GRi s12) + ((fr400 (unit u-trap)) (fr450 (unit u-trap)) + (fr500 (unit u-trap)) (fr550 (unit u-trap))) +) + +(dni tino + "integer trap never" + ((UNIT C) (FR500-MAJOR C-1) (FR550-MAJOR C-1) + (FR400-MAJOR C-1) (FR450-MAJOR C-1)) + "tino$pack" + (+ pack ICC_nev (ICCi_2-null) OP_1C (GRi-null) (s12-null)) + (trap-semantics (const BI 0) GRi s12) + ((fr400 (unit u-trap)) (fr450 (unit u-trap)) + (fr500 (unit u-trap)) (fr550 (unit u-trap))) +) + +(trap-immed ti eq I OP_1C Ieq NA "integer trap equal") +(trap-immed ti ne I OP_1C Ine NA "integer trap not equal") +(trap-immed ti le I OP_1C Ile NA "integer trap less or equal") +(trap-immed ti gt I OP_1C Igt NA "integer trap greater") +(trap-immed ti lt I OP_1C Ilt NA "integer trap less") +(trap-immed ti ge I OP_1C Ige NA "integer trap greater or equal") +(trap-immed ti ls I OP_1C Ils NA "integer trap less or equal unsigned") +(trap-immed ti hi I OP_1C Ihi NA "integer trap greater unsigned") +(trap-immed ti c I OP_1C Ic NA "integer trap carry set") +(trap-immed ti nc I OP_1C Inc NA "integer trap carry clear") +(trap-immed ti n I OP_1C In NA "integer trap negative") +(trap-immed ti p I OP_1C Ip NA "integer trap positive") +(trap-immed ti v I OP_1C Iv NA "integer trap overflow set") +(trap-immed ti nv I OP_1C Inv NA "integer trap overflow clear") + +(dni ftira + "float trap always" + ((UNIT C) (FR500-MAJOR C-1) (FR550-MAJOR C-1) + (FR400-MAJOR C-1) (FR450-MAJOR C-1) FR-ACCESS) + "ftira$pack $GRi,$s12" + (+ pack FCC_ra (ICCi_2-null) OP_1D GRi s12) + (trap-semantics (const BI 1) GRi s12) + ((fr400 (unit u-trap)) + (fr500 (unit u-trap)) (fr550 (unit u-trap))) +) + +(dni ftino + "float trap never" + ((UNIT C) (FR500-MAJOR C-1) (FR550-MAJOR C-1) + (FR400-MAJOR C-1) (FR450-MAJOR C-1) FR-ACCESS) + "ftino$pack" + (+ pack FCC_nev (FCCi_2-null) OP_1D (GRi-null) (s12-null)) + (trap-semantics (const BI 0) GRi s12) + ((fr400 (unit u-trap)) (fr450 (unit u-trap)) + (fr500 (unit u-trap)) (fr550 (unit u-trap))) +) + +(trap-immed fti ne F OP_1D Fne FR-ACCESS "float trap not equal") +(trap-immed fti eq F OP_1D Feq FR-ACCESS "float trap equal") +(trap-immed fti lg F OP_1D Flg FR-ACCESS "float trap greater or less") +(trap-immed fti ue F OP_1D Fue FR-ACCESS "float trap unordered or equal") +(trap-immed fti ul F OP_1D Ful FR-ACCESS "float trap unordered or less") +(trap-immed fti ge F OP_1D Fge FR-ACCESS "float trap greater or equal") +(trap-immed fti lt F OP_1D Flt FR-ACCESS "float trap less") +(trap-immed fti uge F OP_1D Fuge FR-ACCESS "float trap unordered greater or equal") +(trap-immed fti ug F OP_1D Fug FR-ACCESS "float trap unordered or greater") +(trap-immed fti le F OP_1D Fle FR-ACCESS "float trap less or equal") +(trap-immed fti gt F OP_1D Fgt FR-ACCESS "float trap greater") +(trap-immed fti ule F OP_1D Fule FR-ACCESS "float trap unordered less or equal") +(trap-immed fti u F OP_1D Fu FR-ACCESS "float trap unordered") +(trap-immed fti o F OP_1D Fo FR-ACCESS "float trap ordered") + +(dni break + "break trap" + ((UNIT C) (FR500-MAJOR C-1) (FR550-MAJOR C-1) + (FR400-MAJOR C-1) (FR450-MAJOR C-1)) + "break$pack" + (+ pack (rd-null) OP_04 (rs-null) (misc-null-3) OPE4_3 (GRj-null)) + (sequence () + ; This is defered to frv_break because for the breakpoint + ; case we want to change as little of the machine state as + ; possible. + ; + ; BPCSR=PC + ; BPSR.BS=PSR.S + ; BPSR.BET=PSR.ET + ; PSR.S=1 + ; PSR.ET=0 + ; TBR.TT=0xff + ; PC=TBR + ; We still should indicate what is modified by this insn. + (clobber (spr-bpcsr)) + (clobber bpsr_bs) + (clobber bpsr_bet) + (clobber psr_s) + (clobber psr_et) + (clobber tbr_tt) + (c-call VOID "frv_break")) + () +) + +(dni mtrap + "media trap" + ((UNIT C) (FR500-MAJOR C-1) (FR550-MAJOR C-1) + (FR400-MAJOR C-1) (FR450-MAJOR C-1) FR-ACCESS) + "mtrap$pack" + (+ pack (rd-null) OP_04 (rs-null) (misc-null-3) OPE4_2 (GRj-null)) + (c-call VOID "frv_mtrap") + () +) + +(define-pmacro (condition-code-logic name operation ope comment) + (dni name + (comment) + ((UNIT B01) (FR500-MAJOR B-6) (FR550-MAJOR B-6) + (FR400-MAJOR B-6) (FR450-MAJOR B-6)) + (.str name "$pack $CRi,$CRj,$CRk") + (+ pack (misc-null-6) CRk OP_0A (misc-null-7) CRi ope (misc-null-8) CRj) + (set CRk (c-call UQI "@cpu@_cr_logic" operation CRi CRj)) + () + ) +) +(define-pmacro (op-andcr) 0) +(define-pmacro (op-orcr) 1) +(define-pmacro (op-xorcr) 2) +(define-pmacro (op-nandcr) 3) +(define-pmacro (op-norcr) 4) +(define-pmacro (op-andncr) 5) +(define-pmacro (op-orncr) 6) +(define-pmacro (op-nandncr) 7) +(define-pmacro (op-norncr) 8) + +(define-pmacro (cr-true) 3) +(define-pmacro (cr-false) 2) +(define-pmacro (cr-undefined) 0) + +(condition-code-logic andcr (op-andcr) OPE1_08 "and condition code regs") +(condition-code-logic orcr (op-orcr) OPE1_09 "or condition code regs") +(condition-code-logic xorcr (op-xorcr) OPE1_0A "xor condition code regs") +(condition-code-logic nandcr (op-nandcr) OPE1_0C "nand condition code regs") +(condition-code-logic norcr (op-norcr) OPE1_0D "nor condition code regs") +(condition-code-logic andncr (op-andncr) OPE1_10 "andn condition code regs") +(condition-code-logic orncr (op-orncr) OPE1_11 "orn condition code regs") +(condition-code-logic nandncr (op-nandncr) OPE1_14 "nandn condition code regs") +(condition-code-logic norncr (op-norncr) OPE1_15 "norn condition code regs") + +(dni notcr + ("not cccr register") + ((UNIT B01) (FR500-MAJOR B-6) (FR550-MAJOR B-6) + (FR400-MAJOR B-6) (FR450-MAJOR B-6)) + (.str notcr "$pack $CRj,$CRk") + (+ pack (misc-null-6) CRk OP_0A (rs-null) OPE1_0B (misc-null-8) CRj) + (set CRk (xor CRj 1)) + () +) + +(define-pmacro (check-semantics cond cr) + (if cond (set cr (cr-true)) (set cr (cr-false))) +) + +(define-pmacro (check-int-condition-code prefix cc op cond comment) + (dni (.sym prefix cc) + (comment) + ((UNIT B01) (FR500-MAJOR B-5) (FR550-MAJOR B-5) + (FR400-MAJOR B-5) (FR450-MAJOR B-5)) + (.str (.sym prefix cc) "$pack $ICCi_3,$CRj_int") + (+ pack (.sym ICC_ cc) CRj_int op (misc-null-5) ICCi_3) + (check-semantics (cond ICCi_3) CRj_int) + ((fr400 (unit u-check)) (fr450 (unit u-check)) + (fr500 (unit u-check)) (fr550 (unit u-check))) + ) +) + +(dni ckra + "check integer cc always" + ((UNIT B01) (FR500-MAJOR B-5) (FR550-MAJOR B-5) + (FR400-MAJOR B-5) (FR450-MAJOR B-5)) + "ckra$pack $CRj_int" + (+ pack ICC_ra CRj_int OP_08 (misc-null-5) (ICCi_3-null)) + (check-semantics (const BI 1) CRj_int) + ((fr400 (unit u-check)) (fr450 (unit u-check)) + (fr500 (unit u-check)) (fr550 (unit u-check))) +) + +(dni ckno + "check integer cc never" + ((UNIT B01) (FR500-MAJOR B-5) (FR550-MAJOR B-5) + (FR400-MAJOR B-5) (FR450-MAJOR B-5)) + "ckno$pack $CRj_int" + (+ pack ICC_nev CRj_int OP_08 (misc-null-5) (ICCi_3-null)) + (check-semantics (const BI 0) CRj_int) + ((fr400 (unit u-check)) (fr450 (unit u-check)) + (fr500 (unit u-check)) (fr550 (unit u-check))) +) + +(check-int-condition-code ck eq OP_08 Ieq "check integer cc equal") +(check-int-condition-code ck ne OP_08 Ine "check integer cc not equal") +(check-int-condition-code ck le OP_08 Ile "check integer cc less or equal") +(check-int-condition-code ck gt OP_08 Igt "check integer cc greater") +(check-int-condition-code ck lt OP_08 Ilt "check integer cc less") +(check-int-condition-code ck ge OP_08 Ige "check integer cc greater or equal") +(check-int-condition-code ck ls OP_08 Ils "check integer cc less or equal unsigned") +(check-int-condition-code ck hi OP_08 Ihi "check integer cc greater unsigned") +(check-int-condition-code ck c OP_08 Ic "check integer cc carry set") +(check-int-condition-code ck nc OP_08 Inc "check integer cc carry clear") +(check-int-condition-code ck n OP_08 In "check integer cc negative") +(check-int-condition-code ck p OP_08 Ip "check integer cc positive") +(check-int-condition-code ck v OP_08 Iv "check integer cc overflow set") +(check-int-condition-code ck nv OP_08 Inv "check integer cc overflow clear") + +(define-pmacro (check-float-condition-code prefix cc op cond comment) + (dni (.sym prefix cc) + (comment) + ((UNIT B01) (FR500-MAJOR B-5) (FR550-MAJOR B-5) + (FR400-MAJOR B-5) (FR450-MAJOR B-5) FR-ACCESS) + (.str (.sym prefix cc) "$pack $FCCi_3,$CRj_float") + (+ pack (.sym FCC_ cc) CRj_float op (misc-null-5) FCCi_3) + (check-semantics (cond FCCi_3) CRj_float) + ((fr400 (unit u-check)) (fr450 (unit u-check)) + (fr500 (unit u-check)) (fr550 (unit u-check))) + ) +) + +(dni fckra + "check float cc always" + ((UNIT B01) (FR500-MAJOR B-5) (FR550-MAJOR B-5) + (FR400-MAJOR B-5) (FR450-MAJOR B-5) FR-ACCESS) + "fckra$pack $CRj_float" + (+ pack FCC_ra CRj_float OP_09 (misc-null-5) FCCi_3) + (check-semantics (const BI 1) CRj_float) + ((fr400 (unit u-check)) (fr450 (unit u-check)) + (fr500 (unit u-check)) (fr550 (unit u-check))) +) + +(dni fckno + "check float cc never" + ((UNIT B01) (FR500-MAJOR B-5) (FR550-MAJOR B-5) + (FR400-MAJOR B-5) (FR450-MAJOR B-5) FR-ACCESS) + "fckno$pack $CRj_float" + (+ pack FCC_nev CRj_float OP_09 (misc-null-5) FCCi_3) + (check-semantics (const BI 0) CRj_float) + ((fr400 (unit u-check)) (fr450 (unit u-check)) + (fr500 (unit u-check)) (fr550 (unit u-check))) +) + +(check-float-condition-code fck ne OP_09 Fne "check float cc not equal") +(check-float-condition-code fck eq OP_09 Feq "check float cc equal") +(check-float-condition-code fck lg OP_09 Flg "check float cc greater or less") +(check-float-condition-code fck ue OP_09 Fue "check float cc unordered or equal") +(check-float-condition-code fck ul OP_09 Ful "check float cc unordered or less") +(check-float-condition-code fck ge OP_09 Fge "check float cc greater or equal") +(check-float-condition-code fck lt OP_09 Flt "check float cc less") +(check-float-condition-code fck uge OP_09 Fuge "check float cc unordered greater or equal") +(check-float-condition-code fck ug OP_09 Fug "check float cc unordered or greater") +(check-float-condition-code fck le OP_09 Fle "check float cc less or equal") +(check-float-condition-code fck gt OP_09 Fgt "check float cc greater") +(check-float-condition-code fck ule OP_09 Fule "check float cc unordered less or equal") +(check-float-condition-code fck u OP_09 Fu "check float cc unordered") +(check-float-condition-code fck o OP_09 Fo "check float cc ordered") + +(define-pmacro (conditional-check-int-condition-code prefix cc op ope test comment) + (dni (.sym prefix cc) + (comment) + ((UNIT B01) (FR500-MAJOR B-5) (FR550-MAJOR B-5) + (FR400-MAJOR B-5) (FR450-MAJOR B-5) CONDITIONAL) + (.str (.sym prefix cc) "$pack $ICCi_3,$CRj_int,$CCi,$cond") + (+ pack (.sym ICC_ cc) CRj_int op (rs-null) CCi cond ope + (misc-null-9) ICCi_3) + (if (eq CCi (or cond 2)) + (check-semantics (test ICCi_3) CRj_int) + (set CRj_int (cr-undefined))) + ((fr400 (unit u-check)) (fr450 (unit u-check)) + (fr500 (unit u-check)) (fr550 (unit u-check))) + ) +) + +(dni cckra + "conditional check integer cc always" + ((UNIT B01) (FR500-MAJOR B-5) (FR550-MAJOR B-5) + (FR400-MAJOR B-5) (FR450-MAJOR B-5) CONDITIONAL) + "cckra$pack $CRj_int,$CCi,$cond" + (+ pack ICC_ra CRj_int OP_6A (rs-null) CCi cond OPE4_0 + (misc-null-9) (ICCi_3-null)) + (if (eq CCi (or cond 2)) + (check-semantics (const BI 1) CRj_int) + (set CRj_int (cr-undefined))) + ((fr400 (unit u-check)) (fr450 (unit u-check)) + (fr500 (unit u-check)) (fr550 (unit u-check))) +) + +(dni cckno + "conditional check integer cc never" + ((UNIT B01) (FR500-MAJOR B-5) (FR550-MAJOR B-5) + (FR400-MAJOR B-5) (FR450-MAJOR B-5) CONDITIONAL) + "cckno$pack $CRj_int,$CCi,$cond" + (+ pack ICC_nev CRj_int OP_6A (rs-null) CCi cond OPE4_0 + (misc-null-9) (ICCi_3-null)) + (if (eq CCi (or cond 2)) + (check-semantics (const BI 0) CRj_int) + (set CRj_int (cr-undefined))) + ((fr400 (unit u-check)) (fr450 (unit u-check)) + (fr500 (unit u-check)) (fr550 (unit u-check))) +) + +(conditional-check-int-condition-code cck eq OP_6A OPE4_0 Ieq "check integer cc equal") +(conditional-check-int-condition-code cck ne OP_6A OPE4_0 Ine "check integer cc not equal") +(conditional-check-int-condition-code cck le OP_6A OPE4_0 Ile "check integer cc less or equal") +(conditional-check-int-condition-code cck gt OP_6A OPE4_0 Igt "check integer cc greater") +(conditional-check-int-condition-code cck lt OP_6A OPE4_0 Ilt "check integer cc less") +(conditional-check-int-condition-code cck ge OP_6A OPE4_0 Ige "check integer cc greater or equal") +(conditional-check-int-condition-code cck ls OP_6A OPE4_0 Ils "check integer cc less or equal unsigned") +(conditional-check-int-condition-code cck hi OP_6A OPE4_0 Ihi "check integer cc greater unsigned") +(conditional-check-int-condition-code cck c OP_6A OPE4_0 Ic "check integer cc carry set") +(conditional-check-int-condition-code cck nc OP_6A OPE4_0 Inc "check integer cc carry clear") +(conditional-check-int-condition-code cck n OP_6A OPE4_0 In "check integer cc negative") +(conditional-check-int-condition-code cck p OP_6A OPE4_0 Ip "check integer cc positive") +(conditional-check-int-condition-code cck v OP_6A OPE4_0 Iv "check integer cc overflow set") +(conditional-check-int-condition-code cck nv OP_6A OPE4_0 Inv "check integer cc overflow clear") + +(define-pmacro (conditional-check-float-condition-code prefix cc op ope test comment) + (dni (.sym prefix cc) + (comment) + ((UNIT B01) (FR500-MAJOR B-5) (FR550-MAJOR B-5) + (FR400-MAJOR B-5) (FR450-MAJOR B-5) CONDITIONAL FR-ACCESS) + (.str (.sym prefix cc) "$pack $FCCi_3,$CRj_float,$CCi,$cond") + (+ pack (.sym FCC_ cc) CRj_float op (rs-null) CCi cond ope + (misc-null-9) FCCi_3) + (if (eq CCi (or cond 2)) + (check-semantics (test FCCi_3) CRj_float) + (set CRj_float (cr-undefined))) + ((fr400 (unit u-check)) (fr450 (unit u-check)) + (fr500 (unit u-check)) (fr550 (unit u-check))) + ) +) + +(dni cfckra + "conditional check float cc always" + ((UNIT B01) (FR500-MAJOR B-5) (FR550-MAJOR B-5) + (FR400-MAJOR B-5) (FR450-MAJOR B-5) CONDITIONAL FR-ACCESS) + "cfckra$pack $CRj_float,$CCi,$cond" + (+ pack FCC_ra CRj_float OP_6A (rs-null) CCi cond OPE4_1 + (misc-null-9) (FCCi_3-null)) + (if (eq CCi (or cond 2)) + (check-semantics (const BI 1) CRj_float) + (set CRj_float (cr-undefined))) + ((fr400 (unit u-check)) (fr450 (unit u-check)) + (fr500 (unit u-check)) (fr550 (unit u-check))) +) + +(dni cfckno + "conditional check float cc never" + ((UNIT B01) (FR500-MAJOR B-5) (FR550-MAJOR B-5) + (FR400-MAJOR B-5) (FR450-MAJOR B-5) CONDITIONAL FR-ACCESS) + "cfckno$pack $CRj_float,$CCi,$cond" + (+ pack FCC_nev CRj_float OP_6A (rs-null) CCi cond OPE4_1 + (misc-null-9) (FCCi_3-null)) + (if (eq CCi (or cond 2)) + (check-semantics (const BI 0) CRj_float) + (set CRj_float (cr-undefined))) + ((fr400 (unit u-check)) (fr450 (unit u-check)) + (fr500 (unit u-check)) (fr550 (unit u-check))) +) + +(conditional-check-float-condition-code cfck ne OP_6A OPE4_1 Fne "check float cc not equal") +(conditional-check-float-condition-code cfck eq OP_6A OPE4_1 Feq "check float cc equal") +(conditional-check-float-condition-code cfck lg OP_6A OPE4_1 Flg "check float cc greater or less") +(conditional-check-float-condition-code cfck ue OP_6A OPE4_1 Fue "check float cc unordered or equal") +(conditional-check-float-condition-code cfck ul OP_6A OPE4_1 Ful "check float cc unordered or less") +(conditional-check-float-condition-code cfck ge OP_6A OPE4_1 Fge "check float cc greater or equal") +(conditional-check-float-condition-code cfck lt OP_6A OPE4_1 Flt "check float cc less") +(conditional-check-float-condition-code cfck uge OP_6A OPE4_1 Fuge "check float cc unordered greater or equal") +(conditional-check-float-condition-code cfck ug OP_6A OPE4_1 Fug "check float cc unordered or greater") +(conditional-check-float-condition-code cfck le OP_6A OPE4_1 Fle "check float cc less or equal") +(conditional-check-float-condition-code cfck gt OP_6A OPE4_1 Fgt "check float cc greater") +(conditional-check-float-condition-code cfck ule OP_6A OPE4_1 Fule "check float cc unordered less or equal") +(conditional-check-float-condition-code cfck u OP_6A OPE4_1 Fu "check float cc unordered") +(conditional-check-float-condition-code cfck o OP_6A OPE4_1 Fo "check float cc ordered") + +(dni cjmpl + "conditional jump and link" + ((UNIT I0) (FR500-MAJOR I-5) (FR550-MAJOR I-6) + (FR400-MAJOR I-5) (FR450-MAJOR I-5) CONDITIONAL) + "cjmpl$pack @($GRi,$GRj),$CCi,$cond" + (+ pack (misc-null-1) (LI-off) OP_6A GRi CCi cond OPE4_2 GRj) + (if (eq CCi (or cond 2)) + (jump-and-link-semantics GRi GRj LI)) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(dni ccalll + "conditional call and link" + ((UNIT I0) (FR500-MAJOR I-5) (FR550-MAJOR I-6) + (FR400-MAJOR I-5) (FR450-MAJOR I-5) CONDITIONAL) + "ccalll$pack @($GRi,$GRj),$CCi,$cond" + (+ pack (misc-null-1) (LI-on) OP_6A GRi CCi cond OPE4_2 GRj) + (if (eq CCi (or cond 2)) + (jump-and-link-semantics GRi GRj LI)) + ((fr400 (unit u-branch)) (fr450 (unit u-branch)) + (fr500 (unit u-branch)) (fr550 (unit u-branch))) +) + +(define-pmacro (cache-invalidate name cache all op ope profile comment) + (dni name + (comment) + ((UNIT C) (FR500-MAJOR C-2) (FR550-MAJOR C-2) + (FR400-MAJOR C-2) (FR450-MAJOR C-2)) + (.str name "$pack @($GRi,$GRj)") + (+ pack (rd-null) op GRi ope GRj) + (c-call VOID (.str "@cpu@_" cache "_cache_invalidate") (add GRi GRj) all) + profile + ) +) + +(cache-invalidate ici insn 0 OP_03 OPE1_38 + ((fr400 (unit u-ici)) (fr450 (unit u-ici)) + (fr500 (unit u-ici)) (fr550 (unit u-ici))) + "invalidate insn cache") +(cache-invalidate dci data 0 OP_03 OPE1_3C + ((fr400 (unit u-dci)) (fr450 (unit u-dci)) + (fr500 (unit u-dci)) (fr550 (unit u-dci))) + "invalidate data cache") + +(define-pmacro (cache-invalidate-entry name cache op ope profile comment) + (dni name + (comment) + ((UNIT C) (MACH fr400,fr450,fr550) (FR550-MAJOR C-2) + (FR400-MAJOR C-2) (FR450-MAJOR C-2)) + (.str name "$pack @($GRi,$GRj),$ae") + (+ pack (misc-null-1) ae op GRi ope GRj) + (if (eq ae 0) + (c-call VOID (.str "@cpu@_" cache "_cache_invalidate") (add GRi GRj) -1) ; Invalid ae setting for this insn + (c-call VOID (.str "@cpu@_" cache "_cache_invalidate") (add GRi GRj) ae)) + profile + ) +) + +(cache-invalidate-entry icei insn OP_03 OPE1_39 + ((fr400 (unit u-ici)) (fr450 (unit u-ici)) + (fr550 (unit u-ici))) + "invalidate insn cache entry") +(cache-invalidate-entry dcei data OP_03 OPE1_3A + ((fr400 (unit u-dci)) (fr450 (unit u-dci)) + (fr550 (unit u-dci))) + "invalidate data cache entry") + +(dni dcf + "Data cache flush" + ((UNIT C) (FR500-MAJOR C-2) (FR550-MAJOR C-2) + (FR400-MAJOR C-2) (FR450-MAJOR C-2)) + "dcf$pack @($GRi,$GRj)" + (+ pack (rd-null) OP_03 GRi OPE1_3D GRj) + (c-call VOID "@cpu@_data_cache_flush" (add GRi GRj) 0) + ((fr400 (unit u-dcf)) (fr450 (unit u-dcf)) + (fr500 (unit u-dcf)) (fr550 (unit u-dcf))) +) + +(dni dcef + "Data cache entry flush" + ((UNIT C) (MACH fr400,fr450,fr550) (FR550-MAJOR C-2) + (FR400-MAJOR C-2) (FR450-MAJOR C-2)) + "dcef$pack @($GRi,$GRj),$ae" + (+ pack (misc-null-1) ae OP_03 GRi OPE1_3B GRj) + (if (eq ae 0) + (c-call VOID "@cpu@_data_cache_flush" (add GRi GRj) -1) + (c-call VOID "@cpu@_data_cache_flush" (add GRi GRj) ae)) + ((fr400 (unit u-dcf)) (fr450 (unit u-dcf)) (fr550 (unit u-dcf))) +) + +(define-pmacro (write-TLB name insn op ope comment) + (dni name + (comment) + ((UNIT C) (FR500-MAJOR C-2) (MACH frv) PRIVILEGED) + (.str insn "$pack $GRk,@($GRi,$GRj)") + (+ pack GRk op GRi ope GRj) + (nop) ; for now + () + ) +) + +(write-TLB witlb witlb OP_03 OPE1_32 "write for insn TLB") +(write-TLB wdtlb wdtlb OP_03 OPE1_36 "write for data TLB") + +(define-pmacro (invalidate-TLB name insn op ope comment) + (dni name + (comment) + ((UNIT C) (FR500-MAJOR C-2) (MACH frv) PRIVILEGED) + (.str insn "$pack @($GRi,$GRj)") + (+ pack (rd-null) op GRi ope GRj) + (nop) ; for now + () + ) +) + +(invalidate-TLB itlbi itlbi OP_03 OPE1_33 "invalidate insn TLB") +(invalidate-TLB dtlbi dtlbi OP_03 OPE1_37 "invalidate data TLB") + +(define-pmacro (cache-preload name cache pipe attrs op ope profile comment) + (dni name + (comment) + (.splice (UNIT pipe) (FR500-MAJOR C-2) + (FR400-MAJOR C-2) (.unsplice attrs)) + (.str name "$pack $GRi,$GRj,$lock") + (+ pack (misc-null-1) lock op GRi ope GRj) + (c-call VOID (.str "@cpu@_" cache "_cache_preload") GRi GRj lock) + profile + ) +) + +(cache-preload icpl insn C ((FR550-MAJOR C-2) (FR450-MAJOR C-2)) OP_03 OPE1_30 + ((fr400 (unit u-icpl)) (fr450 (unit u-icpl)) + (fr500 (unit u-icpl)) (fr550 (unit u-icpl))) + "preload insn cache") +(cache-preload dcpl data DCPL ((FR550-MAJOR I-8) (FR450-MAJOR I-2)) OP_03 OPE1_34 + ((fr400 (unit u-dcpl)) (fr450 (unit u-dcpl)) + (fr500 (unit u-dcpl)) (fr550 (unit u-dcpl))) + "preload data cache") + +(define-pmacro (cache-unlock name cache op ope profile comment) + (dni name + (comment) + ((UNIT C) (FR500-MAJOR C-2) (FR550-MAJOR C-2) + (FR400-MAJOR C-2) (FR450-MAJOR C-2)) + (.str name "$pack $GRi") + (+ pack (rd-null) op GRi ope (GRj-null)) + (c-call VOID (.str "@cpu@_" cache "_cache_unlock") GRi) + profile + ) +) + +(cache-unlock icul insn OP_03 OPE1_31 + ((fr400 (unit u-icul)) (fr450 (unit u-icul)) + (fr500 (unit u-icul)) (fr550 (unit u-icul))) + "unlock insn cache") +(cache-unlock dcul data OP_03 OPE1_35 + ((fr400 (unit u-dcul)) (fr450 (unit u-dcul)) + (fr500 (unit u-dcul)) (fr550 (unit u-dcul))) + "unlock data cache") + +(define-pmacro (barrier name insn op ope profile comment) + (dni name + (comment) + ((UNIT C) (FR500-MAJOR C-2) (FR550-MAJOR C-2) + (FR400-MAJOR C-2) (FR450-MAJOR C-2)) + (.str insn "$pack") + (+ pack (rd-null) op (rs-null) ope (GRj-null)) + (nop) ; sufficient implementation + profile + ) +) + +(barrier bar bar OP_03 OPE1_3E + ((fr400 (unit u-barrier)) (fr450 (unit u-barrier)) + (fr500 (unit u-barrier))) + "barrier") +(barrier membar membar OP_03 OPE1_3F + ((fr400 (unit u-membar)) (fr450 (unit u-membar)) + (fr500 (unit u-membar))) + "memory barrier") + +; Load real address instructions +(define-pmacro (load-real-address name insn what op ope) + (dni name + (.str "Load real address of " what) + ((UNIT C) (FR450-MAJOR C-2) (MACH fr450)) + (.str insn "$pack $GRi,$GRk,$LRAE,$LRAD,$LRAS") + (+ pack GRk op GRi ope LRAE LRAD LRAS (LRA-null)) + (nop) ; not simulated + () + ) +) + +(load-real-address lrai "lrai" "instruction" OP_03 OPE1_20) +(load-real-address lrad "lrad" "data" OP_03 OPE1_21) + +(dni tlbpr + "TLB Probe" + ((UNIT C) (FR450-MAJOR C-2) (MACH fr450)) + "tlbpr$pack $GRi,$GRj,$TLBPRopx,$TLBPRL" + (+ pack (TLBPR-null) TLBPRopx TLBPRL OP_03 GRi OPE1_24 GRj) + (nop) ; not simulated + () +) + +; Coprocessor operations +(define-pmacro (cop-op num op) + (dni (.sym cop num) + "Coprocessor operation" + ((UNIT C) (FR500-MAJOR C-2) (MACH frv)) + (.str "cop" num "$pack $s6_1,$CPRi,$CPRj,$CPRk") + (+ pack CPRk op CPRi s6_1 CPRj) + (nop) ; sufficient implementation + () + ) +) + +(cop-op 1 OP_7E) +(cop-op 2 OP_7F) + +(define-pmacro (clear-ne-flag-semantics target_index is_float) + (c-call VOID "@cpu@_clear_ne_flags" target_index is_float) +) + +(define-pmacro (clear-ne-flag-r name op ope reg is_float attr profile comment) + (dni name + (comment) + ((UNIT I01) (FR500-MAJOR I-6) (FR550-MAJOR I-7) (MACH simple,tomcat,fr500,fr550,frv) attr) + (.str name "$pack $" reg "k") + (+ pack (.sym reg k) op (rs-null) ope (GRj-null)) + (sequence () + ; hack to get this referenced for profiling + (c-raw-call VOID "frv_ref_SI" (.sym reg k)) + (clear-ne-flag-semantics (index-of (.sym reg k)) is_float)) + profile + ) +) + +(clear-ne-flag-r clrgr OP_0A OPE1_00 GR 0 NA + ((fr500 (unit u-clrgr)) (fr550 (unit u-clrgr))) + "Clear GR NE flag") +(clear-ne-flag-r clrfr OP_0A OPE1_02 FR 1 FR-ACCESS + ((fr500 (unit u-clrfr)) (fr550 (unit u-clrfr))) + "Clear FR NE flag") + +(define-pmacro (clear-ne-flag-all name op ope is_float attr profile comment) + (dni name + (comment) + ((UNIT I01) (FR500-MAJOR I-6) (FR550-MAJOR I-7) (MACH simple,tomcat,fr500,fr550,frv) attr) + (.str name "$pack") + (+ pack (rd-null) op (rs-null) ope (GRj-null)) + (clear-ne-flag-semantics -1 is_float) + profile + ) +) + +(clear-ne-flag-all clrga OP_0A OPE1_01 0 NA + ((fr500 (unit u-clrgr)) (fr550 (unit u-clrgr))) + "Clear GR NE flag ALL") +(clear-ne-flag-all clrfa OP_0A OPE1_03 1 FR-ACCESS + ((fr500 (unit u-clrfr)) (fr550 (unit u-clrfr))) + "Clear FR NE flag ALL") + +(define-pmacro (commit-semantics target_index is_float) + (c-call VOID "@cpu@_commit" target_index is_float) +) + +(define-pmacro (commit-r name op ope reg is_float attr comment) + (dni name + (comment) + ((UNIT I01) (FR500-MAJOR I-6) (FR550-MAJOR I-7) (MACH frv,fr500,fr550) attr) + (.str name "$pack $" reg "k") + (+ pack (.sym reg k) op (rs-null) ope (GRj-null)) + (commit-semantics (index-of (.sym reg k)) is_float) + ((fr500 (unit u-commit)) (fr550 (unit u-commit))) + ) +) + +(commit-r commitgr OP_0A OPE1_04 GR 0 NA "commit exceptions, specific GR") +(commit-r commitfr OP_0A OPE1_06 FR 1 FR-ACCESS "commit exceptions, specific FR") + +(define-pmacro (commit name op ope is_float attr comment) + (dni name + (comment) + ((UNIT I01) (FR500-MAJOR I-6) (FR550-MAJOR I-7) (MACH frv,fr500,fr550) attr) + (.str name "$pack") + (+ pack (rd-null) op (rs-null) ope (GRj-null)) + (commit-semantics -1 is_float) + ((fr500 (unit u-commit)) (fr550 (unit u-commit))) + ) +) + +(commit commitga OP_0A OPE1_05 0 NA "commit exceptions, any GR") +(commit commitfa OP_0A OPE1_07 1 FR-ACCESS "commit exceptions, any FR") + +(define-pmacro (floating-point-conversion + name op ope conv mode src targ attr comment) + (dni name + (comment) + (.splice (UNIT FMALL) (FR500-MAJOR F-1) (.unsplice attr)) + (.str name "$pack $" src ",$" targ) + (+ pack targ op (rs-null) ope src) + (set targ (conv mode src)) + ((fr500 (unit u-float-convert)) (fr550 (unit u-float-convert))) + ) +) + +(floating-point-conversion fitos OP_79 OPE1_00 float SF FRintj FRk + ((FR550-MAJOR F-2) (MACH simple,tomcat,fr500,fr550,frv)) + "Convert Integer to Single") +(floating-point-conversion fstoi OP_79 OPE1_01 fix SI FRj FRintk + ((FR550-MAJOR F-2) (MACH simple,tomcat,fr500,fr550,frv)) + "Convert Single to Integer") +(floating-point-conversion fitod OP_7A OPE1_00 float DF FRintj FRdoublek + ((MACH frv)) + "Convert Integer to Double") +(floating-point-conversion fdtoi OP_7A OPE1_01 fix SI FRdoublej FRintk + ((MACH frv)) + "Convert Double to Integer") + +(define-pmacro (floating-point-dual-conversion + name op ope conv mode src src_hw targ targ_hw attr comment) + (dni name + (comment) + ((MACH frv) (UNIT FMALL) (FR500-MAJOR F-1) attr) + (.str name "$pack $" src ",$" targ) + (+ pack targ op (rs-null) ope src) + (sequence () + (set targ (conv mode src)) + (set (nextreg targ_hw targ 1) + (conv mode (nextreg src_hw src 1)))) + ((fr500 (unit u-float-dual-convert))) + ) +) + +(floating-point-dual-conversion fditos OP_79 OPE1_10 float SF FRintj h-fr_int FRk h-fr NA "Dual Convert Integer to Single") +(floating-point-dual-conversion fdstoi OP_79 OPE1_11 fix SI FRj h-fr FRintk h-fr_int NA "Dual Convert Single to Integer") + +(define-pmacro (ne-floating-point-dual-conversion + name op ope conv mode src src_hw targ targ_hw attr comment) + (dni name + (comment) + ((MACH frv) (UNIT FMALL) (FR500-MAJOR F-1) NON-EXCEPTING attr) + (.str name "$pack $" src ",$" targ) + (+ pack targ op (rs-null) ope src) + (sequence () + (c-call VOID "@cpu@_set_ne_index" (index-of targ)) + (set targ (conv mode src)) + (c-call VOID "@cpu@_set_ne_index" (add (index-of targ) 1)) + (set (nextreg targ_hw targ 1) + (conv mode (nextreg src_hw src 1)))) + ((fr500 (unit u-float-dual-convert))) + ) +) + +(ne-floating-point-dual-conversion nfditos OP_79 OPE1_30 float SF FRintj h-fr_int FRk h-fr NA "Non excepting dual Convert Integer to Single") +(ne-floating-point-dual-conversion nfdstoi OP_79 OPE1_31 fix SI FRj h-fr FRintk h-fr_int NA "Non excepting dual Convert Single to Integer") + +(define-pmacro (conditional-floating-point-conversion + name op ope conv mode src targ comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR F-1) (FR550-MAJOR F-2) (MACH simple,tomcat,fr500,fr550,frv)) + (.str name "$pack $" src ",$" targ ",$CCi,$cond") + (+ pack targ op (rs-null) CCi cond ope src) + (if (eq CCi (or cond 2)) + (set targ (conv mode src))) + ((fr500 (unit u-float-convert)) (fr550 (unit u-float-convert))) + ) +) + +(conditional-floating-point-conversion cfitos OP_6B OPE4_0 float SF FRintj FRk "Conditional convert Integer to Single") +(conditional-floating-point-conversion cfstoi OP_6B OPE4_1 fix SI FRj FRintk "Conditional convert Single to Integer") + +(define-pmacro (ne-floating-point-conversion + name op ope conv mode src targ comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR F-1) (FR550-MAJOR F-2) (MACH simple,tomcat,fr500,fr550,frv)) + (.str name "$pack $" src ",$" targ) + (+ pack targ op (rs-null) ope src) + (sequence () + (c-call VOID "@cpu@_set_ne_index" (index-of targ)) + (set targ (conv mode src))) + ((fr500 (unit u-float-convert)) (fr550 (unit u-float-convert))) + ) +) + +(ne-floating-point-conversion nfitos OP_79 OPE1_20 float SF FRintj FRk "NE convert Integer to Single") +(ne-floating-point-conversion nfstoi OP_79 OPE1_21 fix SI FRj FRintk "NE convert Single to Integer") + +(register-transfer fmovs OP_79 OPE1_02 + FRj FRk FMALL + ((FR500-MAJOR F-1) (FR550-MAJOR F-2) (MACH simple,tomcat,fr500,fr550,frv)) + ((fr500 (unit u-fr2fr))) + "Move Single Float") +(register-transfer fmovd OP_7A OPE1_02 + ; TODO -- unit doesn't handle extra register + FRdoublej FRdoublek FM01 + ((FR500-MAJOR F-1) (MACH frv)) + ((fr500 (unit u-fr2fr)) (fr550 (unit u-fr2fr))) + "Move Double Float") + +(dni fdmovs + "Dual move single float" + ((MACH frv) (UNIT FMALL) (FR500-MAJOR F-1)) + "fdmovs$pack $FRj,$FRk" + (+ pack FRk OP_79 (rs-null) OPE1_12 FRj) + (sequence () + (set FRk FRj) + (set (nextreg h-fr FRk 1) (nextreg h-fr FRj 1))) + ; TODO -- unit doesn't handle extra register + ((fr500 (unit u-fr2fr))) +) + +(conditional-register-transfer cfmovs OP_6C OPE4_0 FRj FRk FMALL + ((FR500-MAJOR F-1) (FR550-MAJOR F-2) + (MACH simple,tomcat,fr500,fr550,frv)) + ((fr500 (unit u-fr2fr)) (fr550 (unit u-fr2fr))) + "Conditional move Single Float") + +(define-pmacro (floating-point-neg name src targ op ope attr comment) + (dni name + (comment) + (.splice (UNIT FMALL) (FR500-MAJOR F-1) (.unsplice attr)) + (.str name "$pack $" src ",$" targ) + (+ pack src op (rs-null) ope targ) + (set targ (neg src)) + ((fr500 (unit u-float-arith)) (fr550 (unit u-float-arith))) + ) +) + +(floating-point-neg fnegs FRj FRk OP_79 OPE1_03 ((FR550-MAJOR F-2) (MACH simple,tomcat,fr500,fr550,frv)) "Floating point negate, single") +(floating-point-neg fnegd FRdoublej FRdoublek OP_7A OPE1_03 ((MACH frv)) "Floating point negate, double") + +(dni fdnegs + "Floating point dual negate, single" + ((MACH frv) (UNIT FMALL) (FR500-MAJOR F-1)) + "fdnegs$pack $FRj,$FRk" + (+ pack FRk OP_79 (rs-null) OPE1_13 FRj) + (sequence () + (set FRk (neg FRj)) + (set (nextreg h-fr FRk 1) (neg (nextreg h-fr FRj 1)))) + ((fr500 (unit u-float-dual-arith))) +) + +(dni cfnegs + "Conditional floating point negate, single" + ((UNIT FMALL) (FR500-MAJOR F-1) (FR550-MAJOR F-2) (MACH simple,tomcat,fr500,fr550,frv)) + "cfnegs$pack $FRj,$FRk,$CCi,$cond" + (+ pack FRj OP_6C (rs-null) CCi cond OPE4_1 FRk) + (if (eq CCi (or cond 2)) + (set FRk (neg FRj))) + ((fr500 (unit u-float-arith)) (fr550 (unit u-float-arith))) +) + +(define-pmacro (float-abs name src targ op ope attr comment) + (dni name + (comment) + (.splice (UNIT FMALL) (FR500-MAJOR F-1) (.unsplice attr)) + (.str name "$pack $" src ",$" targ ) + (+ pack targ op (rs-null) ope src) + (set targ (abs src)) + ((fr500 (unit u-float-arith)) (fr550 (unit u-float-arith))) + ) +) + +(float-abs fabss FRj FRk OP_79 OPE1_04 ((FR550-MAJOR F-2) (MACH simple,tomcat,fr500,fr550,frv)) "Float absolute value, single") +(float-abs fabsd FRdoublej FRdoublek OP_7A OPE1_04 ((MACH frv)) "Float absolute value, double") + +(dni fdabss + "Floating point dual absolute value, single" + ((MACH frv) (UNIT FMALL) (FR500-MAJOR F-1)) + "fdabss$pack $FRj,$FRk" + (+ pack FRk OP_79 (rs-null) OPE1_14 FRj) + (sequence () + (set FRk (abs FRj)) + (set (nextreg h-fr FRk 1) (abs (nextreg h-fr FRj 1)))) + ((fr500 (unit u-float-dual-arith))) +) + +(dni cfabss + "Conditional floating point absolute value, single" + ((UNIT FMALL) (FR500-MAJOR F-1) (FR550-MAJOR F-2) (MACH simple,tomcat,fr500,fr550,frv)) + "cfabss$pack $FRj,$FRk,$CCi,$cond" + (+ pack FRj OP_6C (rs-null) CCi cond OPE4_2 FRk) + (if (eq CCi (or cond 2)) + (set FRk (abs FRj))) + ((fr500 (unit u-float-arith)) (fr550 (unit u-float-arith))) +) + +(dni fsqrts + "Square root single" + ((UNIT FM01) (FR500-MAJOR F-4) (FR550-MAJOR F-3) (MACH simple,tomcat,fr500,fr550,frv)) + "fsqrts$pack $FRj,$FRk" + (+ pack FRk OP_79 (rs-null) OPE1_05 FRj) + (set FRk (sqrt SF FRj)) + ((fr500 (unit u-float-sqrt)) (fr550 (unit u-float-sqrt))) +) + +(dni fdsqrts + "Dual square root single" + ((MACH frv) (UNIT FM01) (FR500-MAJOR F-4)) + "fdsqrts$pack $FRj,$FRk" + (+ pack FRk OP_79 (rs-null) OPE1_15 FRj) + (sequence () + (set FRk (sqrt SF FRj)) + (set (nextreg h-fr FRk 1) (sqrt (nextreg h-fr FRj 1)))) + ((fr500 (unit u-float-dual-sqrt))) +) + +(dni nfdsqrts + "Non excepting Dual square root single" + ((MACH frv) (UNIT FM01) (FR500-MAJOR F-4) NON-EXCEPTING) + "nfdsqrts$pack $FRj,$FRk" + (+ pack FRk OP_79 (rs-null) OPE1_35 FRj) + (sequence () + (c-call VOID "@cpu@_set_ne_index" (index-of FRk)) + (set FRk (sqrt SF FRj)) + (c-call VOID "@cpu@_set_ne_index" (add (index-of FRk) 1)) + (set (nextreg h-fr FRk 1) (sqrt (nextreg h-fr FRj 1)))) + ((fr500 (unit u-float-dual-sqrt))) +) + +(dni fsqrtd + "Square root double" + ((UNIT FM01) (FR500-MAJOR F-4) (MACH frv)) + "fsqrtd$pack $FRdoublej,$FRdoublek" + (+ pack FRdoublek OP_7A (rs-null) OPE1_05 FRdoublej) + (set FRdoublek (sqrt DF FRdoublej)) + ((fr500 (unit u-float-sqrt))) +) + +(dni cfsqrts + "Conditional square root single" + ((UNIT FM01) (FR500-MAJOR F-4) (FR550-MAJOR F-3) (MACH simple,tomcat,fr500,fr550,frv)) + "cfsqrts$pack $FRj,$FRk,$CCi,$cond" + (+ pack FRk OP_6E (rs-null) CCi cond OPE4_2 FRj) + (if (eq CCi (or cond 2)) + (set FRk (sqrt SF FRj))) + ((fr500 (unit u-float-sqrt)) (fr550 (unit u-float-sqrt))) +) + +(dni nfsqrts + "Non exception square root, single" + ((UNIT FM01) (FR500-MAJOR F-4) (FR550-MAJOR F-3) (MACH simple,tomcat,fr500,fr550,frv)) + "nfsqrts$pack $FRj,$FRk" + (+ pack FRk OP_79 (rs-null) OPE1_25 FRj) + (sequence () + (c-call VOID "@cpu@_set_ne_index" (index-of FRk)) + (set FRk (sqrt SF FRj))) + ((fr500 (unit u-float-sqrt)) (fr550 (unit u-float-sqrt))) +) + +(define-pmacro (float-binary-op-s name pipe attr operation op ope comment) + (dni name + (comment) + (.splice (UNIT pipe) (MACH simple,tomcat,fr500,fr550,frv) (.unsplice attr)) + (.str name "$pack $FRi,$FRj,$FRk") + (+ pack FRk op FRi ope FRj) + (set FRk (operation FRi FRj)) + ((fr500 (unit u-float-arith)) (fr550 (unit u-float-arith))) + ) +) + +(float-binary-op-s fadds FMALL ((FR500-MAJOR F-2) (FR550-MAJOR F-2)) add OP_79 OPE1_06 "add single float") +(float-binary-op-s fsubs FMALL ((FR500-MAJOR F-2) (FR550-MAJOR F-2)) sub OP_79 OPE1_07 "sub single float") +(float-binary-op-s fmuls FM01 ((FR500-MAJOR F-3) (FR550-MAJOR F-3)) mul OP_79 OPE1_08 "mul single float") + +(dni fdivs + "div single float" + ((UNIT FM01) (FR500-MAJOR F-4) (FR550-MAJOR F-3) (MACH simple,tomcat,fr500,fr550,frv)) + "fdivs$pack $FRi,$FRj,$FRk" + (+ pack FRk OP_79 FRi OPE1_09 FRj) + (set FRk (div FRi FRj)) + ((fr500 (unit u-float-div)) + (fr550 (unit u-float-div))) +) + +(define-pmacro (float-binary-op-d name operation op ope major comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR major) (MACH frv)) + (.str name "$pack $FRdoublei,$FRdoublej,$FRdoublek") + (+ pack FRdoublek op FRdoublei ope FRdoublej) + (set FRdoublek (operation FRdoublei FRdoublej)) + ((fr500 (unit u-float-arith))) + ) +) + +(float-binary-op-d faddd add OP_7A OPE1_06 F-2 "add double float") +(float-binary-op-d fsubd sub OP_7A OPE1_07 F-2 "sub double float") +(float-binary-op-d fmuld mul OP_7A OPE1_08 F-3 "mul double float") +(float-binary-op-d fdivd div OP_7A OPE1_09 F-4 "div double float") + +(define-pmacro (conditional-float-binary-op name pipe attr operation op ope profile comment) + (dni name + (comment) + (.splice (UNIT pipe) (MACH simple,tomcat,fr500,fr550,frv) + (.unsplice attr)) + (.str name "$pack $FRi,$FRj,$FRk,$CCi,$cond") + (+ pack FRk op FRi CCi cond ope FRj) + (if (eq CCi (or cond 2)) + (set FRk (operation FRi FRj))) + profile + ) +) + +(conditional-float-binary-op cfadds FMALL ((FR500-MAJOR F-2) (FR550-MAJOR F-2)) add OP_6D OPE4_0 + ((fr500 (unit u-float-arith)) (fr550 (unit u-float-arith))) + "cond add single") +(conditional-float-binary-op cfsubs FMALL ((FR500-MAJOR F-2) (FR550-MAJOR F-2)) sub OP_6D OPE4_1 + ((fr500 (unit u-float-arith)) (fr550 (unit u-float-arith))) + "cond sub single") +(conditional-float-binary-op cfmuls FM01 ((FR500-MAJOR F-3) (FR550-MAJOR F-3)) mul OP_6E OPE4_0 + ((fr500 (unit u-float-arith)) (fr550 (unit u-float-arith))) + "cond mul single") +(conditional-float-binary-op cfdivs FM01 ((FR500-MAJOR F-4) (FR550-MAJOR F-3)) div OP_6E OPE4_1 + ((fr500 (unit u-float-div)) (fr550 (unit u-float-div))) + "cond div single") + +(define-pmacro (ne-float-binary-op name pipe attr operation op ope profile comment) + (dni name + (comment) + (.splice (UNIT pipe) (MACH simple,tomcat,fr500,fr550,frv) + (.unsplice attr)) + (.str name "$pack $FRi,$FRj,$FRk") + (+ pack FRk op FRi ope FRj) + (sequence () + (c-call VOID "@cpu@_set_ne_index" (index-of FRk)) + (set FRk (operation FRi FRj))) + profile + ) +) + +(ne-float-binary-op nfadds FMALL ((FR500-MAJOR F-2) (FR550-MAJOR F-2)) add OP_79 OPE1_26 + ((fr500 (unit u-float-arith)) (fr550 (unit u-float-arith))) + "ne add single") +(ne-float-binary-op nfsubs FMALL ((FR500-MAJOR F-2) (FR550-MAJOR F-2)) sub OP_79 OPE1_27 + ((fr500 (unit u-float-arith)) (fr550 (unit u-float-arith))) + "ne sub single") +(ne-float-binary-op nfmuls FM01 ((FR500-MAJOR F-3) (FR550-MAJOR F-3)) mul OP_79 OPE1_28 + ((fr500 (unit u-float-arith)) (fr550 (unit u-float-arith))) + "ne mul single") +(ne-float-binary-op nfdivs FM01 ((FR500-MAJOR F-4) (FR550-MAJOR F-3)) div OP_79 OPE1_29 + ((fr500 (unit u-float-div)) (fr550 (unit u-float-div))) + "ne div single") + +(define-pmacro (fcc-eq) 8) +(define-pmacro (fcc-lt) 4) +(define-pmacro (fcc-gt) 2) +(define-pmacro (fcc-uo) 1) + +(define-pmacro (compare-and-set-fcc arg1 arg2 fcc) + (if (gt arg1 arg2) + (set fcc (fcc-gt)) + (if (eq arg1 arg2) + (set fcc (fcc-eq)) + (if (lt arg1 arg2) + (set fcc (fcc-lt)) + (set fcc (fcc-uo))))) +) + +(dni fcmps + "compare single float" + ((UNIT FMALL) (FR500-MAJOR F-2) (FR550-MAJOR F-2) (MACH simple,tomcat,fr500,fr550,frv)) + "fcmps$pack $FRi,$FRj,$FCCi_2" + (+ pack (cond-null) FCCi_2 OP_79 FRi OPE1_0A FRj) + (compare-and-set-fcc FRi FRj FCCi_2) + ((fr500 (unit u-float-compare)) (fr550 (unit u-float-compare))) +) + +(dni fcmpd + "compare double float" + ((UNIT FMALL) (FR500-MAJOR F-2) (MACH frv)) + "fcmpd$pack $FRdoublei,$FRdoublej,$FCCi_2" + (+ pack (cond-null) FCCi_2 OP_7A FRdoublei OPE1_0A FRdoublej) + (compare-and-set-fcc FRdoublei FRdoublej FCCi_2) + ((fr500 (unit u-float-compare))) +) + +(dni cfcmps + "Conditional compare single, float" + ((UNIT FMALL) (FR500-MAJOR F-2) (FR550-MAJOR F-2) (MACH simple,tomcat,fr500,fr550,frv)) + "cfcmps$pack $FRi,$FRj,$FCCi_2,$CCi,$cond" + (+ pack (cond-null) FCCi_2 OP_6D FRi CCi cond OPE4_2 FRj) + (if (eq CCi (or cond 2)) + (compare-and-set-fcc FRi FRj FCCi_2)) + ((fr500 (unit u-float-compare)) (fr550 (unit u-float-compare))) +) + +(dni fdcmps + "float dual compare single" + ((UNIT FMALL) (FR500-MAJOR F-6) (FR550-MAJOR F-4) (MACH simple,tomcat,fr500,fr550,frv)) + "fdcmps$pack $FRi,$FRj,$FCCi_2" + (+ pack (cond-null) FCCi_2 OP_79 FRi OPE1_1A FRj) + (sequence () + (compare-and-set-fcc FRi FRj FCCi_2) + (compare-and-set-fcc (nextreg h-fr FRi 1) (nextreg h-fr FRj 1) + (nextreg h-fccr FCCi_2 1))) + ((fr500 (unit u-float-dual-compare)) (fr550 (unit u-float-dual-compare))) +) + +(define-pmacro (float-mul-with-add name add_sub arg1 arg2 targ op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR F-5) (MACH frv)) + (.str name "$pack $" arg1 ",$" arg2 ",$" targ) + (+ pack targ op arg1 ope arg2) + (set targ (add_sub (mul arg1 arg2) targ)) + ((fr500 (unit u-float-dual-arith))) + ) +) + +(float-mul-with-add fmadds add FRi FRj FRk OP_79 OPE1_0B "mul with add, single") +(float-mul-with-add fmsubs sub FRi FRj FRk OP_79 OPE1_0C "mul with sub, single") + +(float-mul-with-add fmaddd add FRdoublei FRdoublej FRdoublek OP_7A OPE1_0B "mul with add, double") +(float-mul-with-add fmsubd sub FRdoublei FRdoublej FRdoublek OP_7A OPE1_0C "mul with sub, double") + +(dni fdmadds + "Float dual multiply with add" + ((UNIT FMALL) (FR500-MAJOR F-5) (MACH frv)) + "fdmadds$pack $FRi,$FRj,$FRk" + (+ pack FRk OP_79 FRi OPE1_1B FRj) + (sequence () + (set FRk (add (mul FRi FRj) FRk)) + (set (nextreg h-fr FRk 1) + (add (mul (nextreg h-fr FRi 1) (nextreg h-fr FRj 1)) + (nextreg h-fr FRk 1)))) + ; TODO dual registers not referenced for profiling + ((fr500 (unit u-float-dual-arith))) +) + +(dni nfdmadds + "Non excepting float dual multiply with add" + ((UNIT FMALL) (FR500-MAJOR F-5) (MACH frv)) + "nfdmadds$pack $FRi,$FRj,$FRk" + (+ pack FRk OP_79 FRi OPE1_3B FRj) + (sequence () + (c-call VOID "@cpu@_set_ne_index" (index-of FRk)) + (set FRk (add (mul FRi FRj) FRk)) + (c-call VOID "@cpu@_set_ne_index" (add (index-of FRk) 1)) + (set (nextreg h-fr FRk 1) + (add (mul (nextreg h-fr FRi 1) (nextreg h-fr FRj 1)) + (nextreg h-fr FRk 1)))) + ; TODO dual registers not referenced for profiling + ((fr500 (unit u-float-dual-arith))) +) + +(define-pmacro (conditional-float-mul-with-add + name add_sub arg1 arg2 targ op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR F-5) (MACH frv) CONDITIONAL) + (.str name "$pack $FRi,$FRj,$FRk,$CCi,$cond") + (+ pack FRk op FRi CCi cond ope FRj) + (if (eq CCi (or cond 2)) + (set targ (add_sub (mul arg1 arg2) targ))) + ((fr500 (unit u-float-dual-arith))) + ) +) + +(conditional-float-mul-with-add cfmadds add FRi FRj FRk OP_6F OPE4_0 "conditional mul with add, single") +(conditional-float-mul-with-add cfmsubs sub FRi FRj FRk OP_6F OPE4_1 "conditional mul with sub, single") + +(define-pmacro (ne-float-mul-with-add name add_sub arg1 arg2 targ op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR F-5) (MACH frv) NON-EXCEPTING) + (.str name "$pack $" arg1 ",$" arg2 ",$" targ) + (+ pack targ op arg1 ope arg2) + (sequence () + (c-call VOID "@cpu@_set_ne_index" (index-of targ)) + (set targ (add_sub (mul arg1 arg2) targ))) + ((fr500 (unit u-float-dual-arith))) + ) +) + +(ne-float-mul-with-add nfmadds add FRi FRj FRk OP_79 OPE1_2B "non excepting mul with add, single") +(ne-float-mul-with-add nfmsubs sub FRi FRj FRk OP_79 OPE1_2C "non excepting mul with sub, single") + +(define-pmacro (float-parallel-mul-add-semantics cond add_sub arg1 arg2 targ) + (if cond + (sequence () + (set targ (mul arg1 arg2)) + (set (nextreg h-fr targ 1) + (add_sub (nextreg h-fr arg1 1) (nextreg h-fr arg2 1))))) +) + +(define-pmacro (float-parallel-mul-add + name add_sub arg1 arg2 targ op ope comment) + (dni name + (comment) + ((UNIT FM01) (FR500-MAJOR F-5) (FR550-MAJOR F-4) (MACH simple,tomcat,fr500,fr550,frv)) + (.str name "$pack $" arg1 ",$" arg2 ",$" targ) + (+ pack targ op arg1 ope arg2) + (float-parallel-mul-add-semantics 1 add_sub arg1 arg2 targ) + ((fr500 (unit u-float-dual-arith)) (fr550 (unit u-float-dual-arith))) + ) +) + +(float-parallel-mul-add fmas add FRi FRj FRk OP_79 OPE1_0E "parallel mul/add, single") +(float-parallel-mul-add fmss sub FRi FRj FRk OP_79 OPE1_0F "parallel mul/sub, single") + +(define-pmacro (float-dual-parallel-mul-add-semantics add_sub arg1 arg2 targ) + (sequence () + (set targ (mul arg1 arg2)) + (set (nextreg h-fr targ 1) + (add_sub (nextreg h-fr arg1 1) (nextreg h-fr arg2 1))) + (set (nextreg h-fr targ 2) + (mul (nextreg h-fr arg1 2) (nextreg h-fr arg2 2))) + (set (nextreg h-fr targ 3) + (add_sub (nextreg h-fr arg1 3) (nextreg h-fr arg2 3)))) +) + +(define-pmacro (float-dual-parallel-mul-add + name add_sub arg1 arg2 targ op ope comment) + (dni name + (comment) + ((UNIT FM01) (FR500-MAJOR F-5) (MACH frv)) + (.str name "$pack $" arg1 ",$" arg2 ",$" targ) + (+ pack targ op arg1 ope arg2) + (float-dual-parallel-mul-add-semantics add_sub arg1 arg2 targ) + () + ) +) + +(float-dual-parallel-mul-add fdmas add FRi FRj FRk OP_79 OPE1_1C "dual parallel mul/add, single") +(float-dual-parallel-mul-add fdmss sub FRi FRj FRk OP_79 OPE1_1D "dual parallel mul/sub, single") + +(define-pmacro (ne-float-dual-parallel-mul-add-semantics add_sub arg1 arg2 targ) + (sequence () + (c-call VOID "@cpu@_set_ne_index" (index-of targ)) + (c-call VOID "@cpu@_set_ne_index" (add (index-of targ) 1)) + (c-call VOID "@cpu@_set_ne_index" (add (index-of targ) 2)) + (c-call VOID "@cpu@_set_ne_index" (add (index-of targ) 3)) + (set targ (mul arg1 arg2)) + (set (nextreg h-fr targ 1) + (add_sub (nextreg h-fr arg1 1) (nextreg h-fr arg2 1))) + (set (nextreg h-fr targ 2) + (mul (nextreg h-fr arg1 2) (nextreg h-fr arg2 2))) + (set (nextreg h-fr targ 3) + (add_sub (nextreg h-fr arg1 3) (nextreg h-fr arg2 3)))) +) + +(define-pmacro (ne-float-dual-parallel-mul-add + name add_sub arg1 arg2 targ op ope comment) + (dni name + (comment) + ((UNIT FM01) (FR500-MAJOR F-5) (MACH frv)) + (.str name "$pack $" arg1 ",$" arg2 ",$" targ) + (+ pack targ op arg1 ope arg2) + (ne-float-dual-parallel-mul-add-semantics add_sub arg1 arg2 targ) + () + ) +) + +(ne-float-dual-parallel-mul-add nfdmas add FRi FRj FRk OP_79 OPE1_3C "non excepting dual parallel mul/add, single") +(ne-float-dual-parallel-mul-add nfdmss sub FRi FRj FRk OP_79 OPE1_3D "non excepting dual parallel mul/sub, single") + +(define-pmacro (conditional-float-parallel-mul-add name add_sub op ope comment) + (dni name + (comment) + ((UNIT FM01) (FR500-MAJOR F-5) (FR550-MAJOR F-4) CONDITIONAL (MACH simple,tomcat,fr500,fr550,frv)) + (.str name "$pack $FRi,$FRj,$FRk,$CCi,$cond") + (+ pack FRk op FRi CCi cond ope FRj) + (float-parallel-mul-add-semantics (eq CCi (or cond 2)) + add_sub FRi FRj FRk) + ((fr500 (unit u-float-dual-arith)) (fr550 (unit u-float-dual-arith))) + ) +) + +(conditional-float-parallel-mul-add cfmas add OP_6F OPE4_2 "conditional parallel mul/add, single") +(conditional-float-parallel-mul-add cfmss sub OP_6F OPE4_3 "conditional parallel mul/sub, single") + +(define-pmacro (float-parallel-mul-add-double-semantics add_sub arg1 arg2 targ) + (sequence () + (set targ (ftrunc SF (mul DF (fext DF arg1) (fext DF arg2)))) + (set (nextreg h-fr targ 1) + (ftrunc SF (add_sub DF + (fext DF (nextreg h-fr arg1 1)) + (fext DF (nextreg h-fr arg2 1)))))) +) + +(define-pmacro (float-parallel-mul-add-double + name add_sub arg1 arg2 targ op ope comment) + (dni name + (comment) + ((UNIT FM01) (FR500-MAJOR F-5) (MACH frv)) + (.str name "$pack $" arg1 ",$" arg2 ",$" targ) + (+ pack targ op arg1 ope arg2) + (float-parallel-mul-add-double-semantics add_sub arg1 arg2 targ) + () + ) +) + +(float-parallel-mul-add-double fmad add FRi FRj FRk OP_7A OPE1_0E "parallel mul/add, double") +(float-parallel-mul-add-double fmsd sub FRi FRj FRk OP_7A OPE1_0F "parallel mul/sub, double") + +(define-pmacro (ne-float-parallel-mul-add name add_sub op ope comment) + (dni name + (comment) + ((UNIT FM01) (FR500-MAJOR F-5) (FR550-MAJOR F-4) (MACH simple,tomcat,fr500,fr550,frv)) + (.str name "$pack $FRi,$FRj,$FRk") + (+ pack FRk op FRi ope FRj) + (sequence () + (c-call VOID "@cpu@_set_ne_index" (index-of FRk)) + (set FRk (mul FRi FRj)) + (c-call VOID "@cpu@_set_ne_index" (add (index-of FRk) 1)) + (set (nextreg h-fr FRk 1) + (add_sub (nextreg h-fr FRi 1) (nextreg h-fr FRj 1)))) + ((fr500 (unit u-float-dual-arith)) (fr550 (unit u-float-dual-arith))) + ) +) + +(ne-float-parallel-mul-add nfmas add OP_79 OPE1_2E "ne parallel mul/add,single") +(ne-float-parallel-mul-add nfmss sub OP_79 OPE1_2F "ne parallel mul/sub,single") + +(define-pmacro (float-dual-arith name attr oper1 oper2 op ope comment) + (dni name + (comment) + (.splice (UNIT FM01) (.unsplice attr)) + (.str name "$pack $FRi,$FRj,$FRk") + (+ pack FRk op FRi ope FRj) + (sequence () + (set FRk (oper1 FRi FRj)) + (set (nextreg h-fr FRk 1) + (oper2 (nextreg h-fr FRi 1) (nextreg h-fr FRj 1)))) + ((fr500 (unit u-float-dual-arith)) (fr550 (unit u-float-dual-arith))) + ) +) + +(float-dual-arith fdadds ((FR500-MAJOR F-6) (FR550-MAJOR F-4) (MACH simple,tomcat,fr500,fr550,frv)) add add OP_79 OPE1_16 "dual add, single") +(float-dual-arith fdsubs ((FR500-MAJOR F-6) (FR550-MAJOR F-4) (MACH simple,tomcat,fr500,fr550,frv)) sub sub OP_79 OPE1_17 "dual sub, single") +(float-dual-arith fdmuls ((FR500-MAJOR F-7) (FR550-MAJOR F-4) (MACH simple,tomcat,fr500,fr550,frv)) mul mul OP_79 OPE1_18 "dual mul, single") +(float-dual-arith fddivs ((FR500-MAJOR F-7) (MACH frv)) div div OP_79 OPE1_19 "dual div,single") +(float-dual-arith fdsads ((FR500-MAJOR F-6) (FR550-MAJOR F-4) (MACH simple,tomcat,fr500,fr550,frv)) add sub OP_79 OPE1_1E "dual add/sub, single") + +(dni fdmulcs + "Float dual cross multiply single" + ((UNIT FM01) (FR500-MAJOR F-7) (FR550-MAJOR F-4) (MACH simple,tomcat,fr500,fr550,frv)) + "fdmulcs$pack $FRi,$FRj,$FRk" + (+ pack FRk OP_79 FRi OPE1_1F FRj) + (sequence () + (set FRk (mul FRi (nextreg h-fr FRj 1))) + (set (nextreg h-fr FRk 1) (mul (nextreg h-fr FRi 1) FRj))) + ((fr500 (unit u-float-dual-arith)) (fr550 (unit u-float-dual-arith))) +) + +(dni nfdmulcs + "NE float dual cross multiply single" + ((UNIT FM01) (FR500-MAJOR F-7) (FR550-MAJOR F-4) (MACH simple,tomcat,fr500,fr550,frv)) + "nfdmulcs$pack $FRi,$FRj,$FRk" + (+ pack FRk OP_79 FRi OPE1_3F FRj) + (sequence () + (c-call VOID "@cpu@_set_ne_index" (index-of FRk)) + (set FRk (mul FRi (nextreg h-fr FRj 1))) + (c-call VOID "@cpu@_set_ne_index" (add (index-of FRk) 1)) + (set (nextreg h-fr FRk 1) (mul (nextreg h-fr FRi 1) FRj))) + ((fr500 (unit u-float-dual-arith)) (fr550 (unit u-float-dual-arith))) +) + +(define-pmacro (ne-float-dual-arith name attr oper1 oper2 op ope comment) + (dni name + (comment) + (.splice (UNIT FM01) (.unsplice attr)) + (.str name "$pack $FRi,$FRj,$FRk") + (+ pack FRk op FRi ope FRj) + (sequence () + (c-call VOID "@cpu@_set_ne_index" (index-of FRk)) + (set FRk (oper1 FRi FRj)) + (c-call VOID "@cpu@_set_ne_index" (add (index-of FRk) 1)) + (set (nextreg h-fr FRk 1) + (oper2 (nextreg h-fr FRi 1) (nextreg h-fr FRj 1)))) + ((fr500 (unit u-float-dual-arith)) (fr550 (unit u-float-dual-arith))) + ) +) + +(ne-float-dual-arith nfdadds ((FR500-MAJOR F-6) (FR550-MAJOR F-4) (MACH simple,tomcat,fr500,fr550,frv)) add add OP_79 OPE1_36 "ne dual add, single") +(ne-float-dual-arith nfdsubs ((FR500-MAJOR F-6) (FR550-MAJOR F-4) (MACH simple,tomcat,fr500,fr550,frv)) sub sub OP_79 OPE1_37 "ne dual sub, single") +(ne-float-dual-arith nfdmuls ((FR500-MAJOR F-7) (FR550-MAJOR F-4) (MACH simple,tomcat,fr500,fr550,frv)) mul mul OP_79 OPE1_38 "ne dual mul, single") +(ne-float-dual-arith nfddivs ((FR500-MAJOR F-7) (MACH frv)) div div OP_79 OPE1_39 "ne dual div,single") +(ne-float-dual-arith nfdsads ((FR500-MAJOR F-6) (FR550-MAJOR F-4) (MACH simple,tomcat,fr500,fr550,frv)) add sub OP_79 OPE1_3E "ne dual add/sub, single") + +(dni nfdcmps + "non-excepting dual float compare" + ((UNIT FM01) (FR500-MAJOR F-6) (MACH simple,tomcat,frv)) + "nfdcmps$pack $FRi,$FRj,$FCCi_2" + (+ pack (cond-null) FCCi_2 OP_79 FRi OPE1_3A FRj) + (sequence () + (c-call VOID "@cpu@_set_ne_index" (index-of FRk)) + (compare-and-set-fcc FRi FRj FCCi_2) + (c-call VOID "@cpu@_set_ne_index" (add (index-of FRk) 1)) + (compare-and-set-fcc (nextreg h-fr FRi 1) (nextreg h-fr FRj 1) + (nextreg h-fccr FCCi_2 1))) + ((fr500 (unit u-float-dual-compare))) +) + +; Media Instructions +; +(define-pmacro (halfword hilo arg offset) + (reg (.sym h-fr_ hilo) (add (index-of arg) offset))) + +(dni mhsetlos + "Media set lower signed 12 bits" + ((UNIT FMALL) (MACH fr400,fr450,fr550) (FR550-MAJOR M-5) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + "mhsetlos$pack $u12,$FRklo" + (+ pack FRklo OP_78 OPE1_20 u12) + (set FRklo u12) + ((fr400 (unit u-media-hilo)) (fr450 (unit u-media-hilo)) + (fr550 (unit u-media-set (out FRintk FRklo)))) +) + +(dni mhsethis + "Media set upper signed 12 bits" + ((UNIT FMALL) (MACH fr400,fr450,fr550) (FR550-MAJOR M-5) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + "mhsethis$pack $u12,$FRkhi" + (+ pack FRkhi OP_78 OPE1_22 u12) + (set FRkhi u12) + ((fr400 (unit u-media-hilo)) (fr450 (unit u-media-hilo)) + (fr550 (unit u-media-set (out FRintk FRkhi)))) +) + +(dni mhdsets + "Media dual set halfword signed 12 bits" + ((UNIT FMALL) (MACH fr400,fr450,fr550) (FR550-MAJOR M-5) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + "mhdsets$pack $u12,$FRintk" + (+ pack FRintk OP_78 OPE1_24 u12) + (sequence () + ; hack to get FRintk passed to modelling functions + (set FRintk (c-raw-call SI "frv_ref_SI" FRintk)) + (set (halfword hi FRintk 0) u12) + (set (halfword lo FRintk 0) u12)) + ((fr400 (unit u-media-1)) (fr450 (unit u-media-1)) + (fr550 (unit u-media-set))) +) + +(define-pmacro (set-5-semantics target value) + (sequence ((HI tmp)) + (set tmp target) + (set tmp (and tmp #x07ff)) + (set tmp (or tmp (sll (and s5 #x1f) 11))) + (set target tmp)) +) + +(define-pmacro (media-set-5 name hilo op ope comment) + (dni name + (comment) + ((UNIT FMALL) (MACH fr400,fr450,fr550) (FR550-MAJOR M-5) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + (.str name "$pack $s5,$FRk" hilo) + (+ pack (.sym FRk hilo) op (FRi-null) ope (misc-null-11) s5) + (set-5-semantics (.sym FRk hilo) s5) + ((fr400 (unit u-media-hilo)) (fr450 (unit u-media-hilo)) + (fr550 (unit u-media-set (out FRintk (.sym FRk hilo))))) + ) +) + +(media-set-5 mhsetloh lo OP_78 OPE1_21 "Media set upper 5 bits lo") +(media-set-5 mhsethih hi OP_78 OPE1_23 "Media set upper 5 bits hi") + +(dni mhdseth + "Media dual set halfword upper 5 bits" + ((UNIT FMALL) (MACH fr400,fr450,fr550) (FR550-MAJOR M-5) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + "mhdseth$pack $s5,$FRintk" + (+ pack FRintk OP_78 (FRi-null) OPE1_25 (misc-null-11) s5) + (sequence () + ; hack to get FRintk passed to modelling functions + (set FRintk (c-raw-call SI "frv_ref_SI" FRintk)) + (set-5-semantics (halfword hi FRintk 0) s5) + (set-5-semantics (halfword lo FRintk 0) s5)) + ((fr400 (unit u-media-1)) (fr450 (unit u-media-1)) + (fr550 (unit u-media-set))) +) + +(define-pmacro (media-logic-r-r name operation op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-1) (FR550-MAJOR M-2) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + (.str name "$pack $FRinti,$FRintj,$FRintk") + (+ pack FRintk op FRinti ope FRintj) + (set FRintk (operation FRinti FRintj)) + ((fr400 (unit u-media-1)) (fr450 (unit u-media-1)) + (fr500 (unit u-media)) (fr550 (unit u-media))) + ) +) + +(media-logic-r-r mand and OP_7B OPE1_00 "and reg/reg") +(media-logic-r-r mor or OP_7B OPE1_01 "or reg/reg") +(media-logic-r-r mxor xor OP_7B OPE1_02 "xor reg/reg") + +(define-pmacro (conditional-media-logic name operation op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-1) (FR550-MAJOR M-2) + (FR400-MAJOR M-1) (FR450-MAJOR M-1) CONDITIONAL) + (.str name "$pack $FRinti,$FRintj,$FRintk,$CCi,$cond") + (+ pack FRintk op FRinti CCi cond ope FRintj) + (if (eq CCi (or cond 2)) + (set FRintk (operation FRinti FRintj))) + ((fr400 (unit u-media-1)) (fr450 (unit u-media-1)) + (fr500 (unit u-media)) (fr550 (unit u-media))) + ) +) + +(conditional-media-logic cmand and OP_70 OPE4_0 "conditional and reg/reg") +(conditional-media-logic cmor or OP_70 OPE4_1 "conditional or reg/reg") +(conditional-media-logic cmxor xor OP_70 OPE4_2 "conditional xor reg/reg") + +(dni mnot + ("mnot") + ((UNIT FMALL) (FR500-MAJOR M-1) (FR550-MAJOR M-2) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + ("mnot$pack $FRintj,$FRintk") + (+ pack FRintk OP_7B (rs-null) OPE1_03 FRintj) + (set FRintk (inv FRintj)) + ((fr400 (unit u-media-1)) (fr450 (unit u-media-1)) + (fr500 (unit u-media)) (fr550 (unit u-media))) +) + +(dni cmnot + ("cmnot") + ((UNIT FMALL) (FR500-MAJOR M-1) (FR550-MAJOR M-2) + (FR400-MAJOR M-1) (FR450-MAJOR M-1) CONDITIONAL) + ("cmnot$pack $FRintj,$FRintk,$CCi,$cond") + (+ pack FRintk OP_70 (rs-null) CCi cond OPE4_3 FRintj) + (if (eq CCi (or cond 2)) + (set FRintk (inv FRintj))) + ((fr400 (unit u-media-1)) (fr450 (unit u-media-1)) + (fr500 (unit u-media)) (fr550 (unit u-media))) +) + +(define-pmacro (media-rotate-r-r name operation op ope comment) + (dni name + (comment) + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + (.str name "$pack $FRinti,$u6,$FRintk") + (+ pack FRintk op FRinti ope u6) + (set FRintk (operation FRinti (and u6 #x1f))) + ((fr400 (unit u-media-3)) (fr450 (unit u-media-3)) + (fr500 (unit u-media)) (fr550 (unit u-media))) + ) +) + +(media-rotate-r-r mrotli rol OP_7B OPE1_04 "rotate left reg/reg") +(media-rotate-r-r mrotri ror OP_7B OPE1_05 "rotate right reg/reg") + +(define-pmacro (media-cut-r-r name arg op ope comment) + (dni name + (comment) + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-2) (FR450-MAJOR M-2)) + (.str name "$pack $FRinti,$" arg ",$FRintk") + (+ pack FRintk op FRinti ope arg) + (set FRintk (c-call SI "@cpu@_cut" FRinti (nextreg h-fr_int FRinti 1) arg)) + ((fr400 (unit u-media-3)) (fr450 (unit u-media-3)) + (fr500 (unit u-media)) (fr550 (unit u-media))) + ) +) + +(media-cut-r-r mwcut FRintj OP_7B OPE1_06 "media cut") +(media-cut-r-r mwcuti u6 OP_7B OPE1_07 "media cut") + +(define-pmacro (media-cut-acc name arg op ope fr450-major comment) + (dni name + (comment) + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-1) (FR450-MAJOR fr450-major)) + (.str name "$pack $ACC40Si,$" arg ",$FRintk") + (+ pack FRintk op ACC40Si ope arg) + (set FRintk (c-call SI "@cpu@_media_cut" ACC40Si arg)) + ((fr400 (unit u-media-4)) (fr450 (unit u-media-4)) + (fr500 (unit u-media)) (fr550 (unit u-media-3-acc))) + ) +) + +(media-cut-acc mcut FRintj OP_7B OPE1_2C M-1 "media accumulator cut reg") +(media-cut-acc mcuti s6 OP_7B OPE1_2E M-5 "media accumulator cut immed") + +(define-pmacro (media-cut-acc-ss name arg op ope fr450-major comment) + (dni name + (comment) + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-1) (FR450-MAJOR fr450-major)) + (.str name "$pack $ACC40Si,$" arg ",$FRintk") + (+ pack FRintk op ACC40Si ope arg) + (set FRintk (c-call SI "@cpu@_media_cut_ss" ACC40Si arg)) + ((fr400 (unit u-media-4)) (fr450 (unit u-media-4)) + (fr500 (unit u-media)) (fr550 (unit u-media-3-acc))) + ) +) + +(media-cut-acc-ss mcutss FRintj OP_7B OPE1_2D M-1 "media accumulator cut reg with saturation") +(media-cut-acc-ss mcutssi s6 OP_7B OPE1_2F M-5 "media accumulator cut immed with saturation") + +; Dual Media Instructions +; +(define-pmacro (register-unaligned register alignment) + (and (index-of register) (sub alignment 1)) +) + +(dni mdcutssi + "Media dual cut with signed saturation" + ((UNIT MDCUTSSI) (MACH fr400,fr450,fr550) (FR550-MAJOR M-3) + (FR400-MAJOR M-2) (FR450-MAJOR M-6)) + "mdcutssi$pack $ACC40Si,$s6,$FRintkeven" + (+ pack FRintkeven OP_78 ACC40Si OPE1_0E s6) + (if (register-unaligned ACC40Si 2) + (c-call VOID "@cpu@_media_acc_not_aligned") + (if (register-unaligned FRintkeven 2) + (c-call VOID "@cpu@_media_register_not_aligned") + (sequence () + (set FRintkeven (c-call SI "@cpu@_media_cut_ss" ACC40Si s6)) + (set (nextreg h-fr_int FRintkeven 1) + (c-call SI "@cpu@_media_cut_ss" + (nextreg h-acc40S ACC40Si 1) s6))))) + ((fr400 (unit u-media-4-acc-dual + (out FRintk FRintkeven))) + (fr450 (unit u-media-4-acc-dual + (out FRintk FRintkeven))) + (fr550 (unit u-media-3-acc-dual))) +) + +; The (add (xxxx) (mul arg 0)) is a hack to get a reference to arg generated +; so it will be passed to the unit modelers. YUCK!!!!! +(define-pmacro (extract-hilo reg1 off1 reg2 off2 arg1hi arg1lo arg2hi arg2lo) + (sequence () + (set arg1hi (add (halfword hi reg1 off1) (mul reg1 0))) + (set arg1lo (add (halfword lo reg1 off1) (mul reg1 0))) + (set arg2hi (add (halfword hi reg2 off2) (mul reg2 0))) + (set arg2lo (add (halfword lo reg2 off2) (mul reg2 0)))) +) + +(dni maveh + "Media dual average" + ((UNIT FMALL) (FR500-MAJOR M-1) (FR550-MAJOR M-2) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + "maveh$pack $FRinti,$FRintj,$FRintk" + (+ pack FRintk OP_7B FRinti OPE1_08 FRintj) + (set FRintk (c-call SI "@cpu@_media_average" FRinti FRintj)) + ((fr400 (unit u-media-1)) (fr450 (unit u-media-1)) + (fr500 (unit u-media)) (fr550 (unit u-media))) +) + +(define-pmacro (media-dual-shift name operation op ope profile comment) + (dni name + (comment) + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + (.str name "$pack $FRinti,$u6,$FRintk") + (+ pack FRintk op FRinti ope u6) + (sequence () + ; hack to get these referenced for profiling + (set FRinti (c-raw-call SI "frv_ref_SI" FRinti)) + (set FRintk (c-raw-call SI "frv_ref_SI" FRintk)) + (set (halfword hi FRintk 0) + (operation (halfword hi FRinti 0) (and u6 #xf))) + (set (halfword lo FRintk 0) + (operation (halfword lo FRinti 0) (and u6 #xf)))) + profile + ) +) + +(media-dual-shift msllhi sll OP_7B OPE1_09 + ((fr400 (unit u-media-3)) (fr450 (unit u-media-3)) + (fr500 (unit u-media)) (fr550 (unit u-media))) + "Media dual shift left logical") +(media-dual-shift msrlhi srl OP_7B OPE1_0A + ((fr400 (unit u-media-3)) (fr450 (unit u-media-3)) + (fr500 (unit u-media)) (fr550 (unit u-media))) + "Media dual shift right logical") +(media-dual-shift msrahi sra OP_7B OPE1_0B + ((fr400 (unit u-media-6)) (fr450 (unit u-media-6)) + (fr500 (unit u-media)) (fr550 (unit u-media))) + "Media dual shift right arithmetic") + +(define-pmacro (media-dual-word-rotate-r-r name operation op ope comment) + (dni name + (comment) + ((UNIT FMLOW) (MACH fr400,fr450,fr550) (FR550-MAJOR M-3) + (FR400-MAJOR M-2) (FR450-MAJOR M-2)) + (.str name "$pack $FRintieven,$s6,$FRintkeven") + (+ pack FRintkeven op FRintieven ope s6) + (if (orif (register-unaligned FRintieven 2) + (register-unaligned FRintkeven 2)) + (c-call VOID "@cpu@_media_register_not_aligned") + (sequence () + (set FRintkeven (operation FRintieven (and s6 #x1f))) + (set (nextreg h-fr_int FRintkeven 1) + (operation (nextreg h-fr_int FRintieven 1) + (and s6 #x1f))))) + ((fr400 (unit u-media-3-quad + (in FRinti FRintieven) + (out FRintk FRintkeven))) + (fr450 (unit u-media-3-quad + (in FRinti FRintieven) + (out FRintk FRintkeven))) + (fr550 (unit u-media-quad))) + ) +) + +(media-dual-word-rotate-r-r mdrotli rol OP_78 OPE1_0B "rotate left reg/reg") + +(dni mcplhi + "Media bit concatenate, halfword" + ((UNIT FMLOW) (MACH fr400,fr450,fr550) (FR550-MAJOR M-3) + (FR400-MAJOR M-2) (FR450-MAJOR M-2)) + "mcplhi$pack $FRinti,$u6,$FRintk" + (+ pack FRintk OP_78 FRinti OPE1_0C u6) + (sequence ((HI arg1) (HI arg2) (HI shift)) + (set FRinti (c-raw-call SI "frv_ref_SI" FRinti)) + (set FRintk (c-raw-call SI "frv_ref_SI" FRintk)) + (set shift (and u6 #xf)) + (set arg1 (sll (halfword hi FRinti 0) shift)) + (if (ne shift 0) + (sequence () + (set arg2 (halfword hi FRinti 1)) + (set arg2 (srl HI (sll HI arg2 (sub 15 shift)) + (sub 15 shift))) + (set arg1 (or HI arg1 arg2)))) + (set (halfword hi FRintk 0) arg1)) + ((fr400 (unit u-media-3-dual)) (fr450 (unit u-media-3-dual)) + (fr550 (unit u-media-3-dual))) +) + +(dni mcpli + "Media bit concatenate, word" + ((UNIT FMLOW) (MACH fr400,fr450,fr550) (FR550-MAJOR M-3) + (FR400-MAJOR M-2) (FR450-MAJOR M-2)) + "mcpli$pack $FRinti,$u6,$FRintk" + (+ pack FRintk OP_78 FRinti OPE1_0D u6) + (sequence ((SI tmp) (SI shift)) + (set shift (and u6 #x1f)) + (set tmp (sll FRinti shift)) + (if (ne shift 0) + (sequence ((SI tmp1)) + (set tmp1 (srl (sll (nextreg h-fr_int FRinti 1) + (sub 31 shift)) + (sub 31 shift))) + (set tmp (or tmp tmp1)))) + (set FRintk tmp)) + ((fr400 (unit u-media-3-dual)) (fr450 (unit u-media-3-dual)) + (fr550 (unit u-media-3-dual))) +) + +(define-pmacro (saturate arg max min result) + (if (gt arg max) + (set result max) + (if (lt arg min) + (set result min) + (set result arg))) +) + +(dni msaths + "Media dual saturation signed" + ((UNIT FMALL) (FR500-MAJOR M-1) (FR550-MAJOR M-2) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + "msaths$pack $FRinti,$FRintj,$FRintk" + (+ pack FRintk OP_7B FRinti OPE1_0C FRintj) + (sequence ((HI argihi) (HI argilo) (HI argjhi) (HI argjlo)) + (extract-hilo FRinti 0 FRintj 0 argihi argilo argjhi argjlo) + (saturate argihi argjhi (inv argjhi) (halfword hi FRintk 0)) + (saturate argilo argjlo (inv argjlo) (halfword lo FRintk 0))) + ((fr400 (unit u-media-1)) (fr450 (unit u-media-1)) + (fr500 (unit u-media)) (fr550 (unit u-media))) +) + +(dni mqsaths + "Media quad saturation signed" + ((UNIT FMALL) (MACH fr400,fr450,fr550) (FR550-MAJOR M-2) + (FR400-MAJOR M-2) (FR450-MAJOR M-2)) + "mqsaths$pack $FRintieven,$FRintjeven,$FRintkeven" + (+ pack FRintkeven OP_78 FRintieven OPE1_0F FRintjeven) + (if (orif (register-unaligned FRintieven 2) + (orif (register-unaligned FRintjeven 2) + (register-unaligned FRintkeven 2))) + (c-call VOID "@cpu@_media_register_not_aligned") + (sequence ((HI argihi) (HI argilo) (HI argjhi) (HI argjlo)) + ; hack to get FRintkeven referenced as a target for profiling + (set FRintkeven (c-raw-call SI "frv_ref_SI" FRintkeven)) + (extract-hilo FRintieven 0 FRintjeven 0 argihi argilo argjhi argjlo) + (saturate argihi argjhi (inv argjhi) (halfword hi FRintkeven 0)) + (saturate argilo argjlo (inv argjlo) (halfword lo FRintkeven 0)) + (extract-hilo FRintieven 1 FRintjeven 1 argihi argilo argjhi argjlo) + (saturate argihi argjhi (inv argjhi) (halfword hi FRintkeven 1)) + (saturate argilo argjlo (inv argjlo) (halfword lo FRintkeven 1)))) + ((fr400 (unit u-media-1-quad + (in FRinti FRintieven) + (in FRintj FRintjeven) + (out FRintk FRintkeven))) + (fr450 (unit u-media-1-quad + (in FRinti FRintieven) + (in FRintj FRintjeven) + (out FRintk FRintkeven))) + (fr550 (unit u-media-quad))) +) + +(define-pmacro (saturate-unsigned arg max result) + (if (gt arg max) + (set result max) + (set result arg)) +) + +(dni msathu + "Media dual saturation unsigned" + ((UNIT FMALL) (FR500-MAJOR M-1) (FR550-MAJOR M-2) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + "msathu$pack $FRinti,$FRintj,$FRintk" + (+ pack FRintk OP_7B FRinti OPE1_0D FRintj) + (sequence ((UHI argihi) (UHI argilo) (UHI argjhi) (UHI argjlo)) + (extract-hilo FRinti 0 FRintj 0 argihi argilo argjhi argjlo) + (saturate-unsigned argihi argjhi (halfword hi FRintk 0)) + (saturate-unsigned argilo argjlo (halfword lo FRintk 0))) + ((fr400 (unit u-media-1)) (fr450 (unit u-media-1)) + (fr500 (unit u-media)) (fr550 (unit u-media))) +) + +(define-pmacro (media-dual-compare name mode op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-1) (FR550-MAJOR M-2) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + (.str name "$pack $FRinti,$FRintj,$FCCk") + (+ pack (cond-null) FCCk op FRinti ope FRintj) + (if (register-unaligned FCCk 2) + (c-call VOID "@cpu@_media_cr_not_aligned") + (sequence ((mode argihi) (mode argilo) (mode argjhi) (mode argjlo)) + (extract-hilo FRinti 0 FRintj 0 + argihi argilo argjhi argjlo) + (compare-and-set-fcc argihi argjhi FCCk) + (compare-and-set-fcc argilo argjlo (nextreg h-fccr FCCk 1)))) + ; TODO - doesn't handle second FCC + ((fr400 (unit u-media-7)) (fr450 (unit u-media-7)) + (fr500 (unit u-media)) (fr550 (unit u-media))) + ) +) + +(media-dual-compare mcmpsh HI OP_7B OPE1_0E "Media dual compare signed") +(media-dual-compare mcmpuh UHI OP_7B OPE1_0F "Media dual compare unsigned") + +; Bits for the MSR.SIE field +(define-pmacro (msr-sie-nil) 0) +(define-pmacro (msr-sie-fri-hi) 8) +(define-pmacro (msr-sie-fri-lo) 4) +(define-pmacro (msr-sie-fri-1-hi) 2) +(define-pmacro (msr-sie-fri-1-lo) 1) +(define-pmacro (msr-sie-acci) 8) +(define-pmacro (msr-sie-acci-1) 4) +(define-pmacro (msr-sie-acci-2) 2) +(define-pmacro (msr-sie-acci-3) 1) + +(define-pmacro (saturate-v arg max min sie result) + (if (gt DI arg max) + (sequence () + (set result max) + (c-call VOID "@cpu@_media_overflow" sie)) + (if (lt DI arg min) + (sequence () + (set result min) + (c-call VOID "@cpu@_media_overflow" sie)) + (set result arg))) +) + +(dni mabshs + "Media dual absolute value, halfword" + ((UNIT FMALL) (MACH fr400,fr450,fr550) (FR550-MAJOR M-2) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + "mabshs$pack $FRintj,$FRintk" + (+ pack FRintk OP_78 (FRi-null) OPE1_0A FRintj) + (sequence ((HI arghi) (HI arglo)) + (set FRintj (c-raw-call SI "frv_ref_SI" FRintj)) + (set FRintk (c-raw-call SI "frv_ref_SI" FRintk)) + (set arghi (halfword hi FRintj 0)) + (set arglo (halfword lo FRintj 0)) + ; We extend the argument before the abs operation so we can + ; notice -32768 overflowing as 32768. + (saturate-v (abs (ext DI arghi)) 32767 -32768 (msr-sie-fri-hi) + (halfword hi FRintk 0)) + (saturate-v (abs (ext DI arglo)) 32767 -32768 (msr-sie-fri-lo) + (halfword lo FRintk 0))) + ((fr400 (unit u-media-1)) (fr450 (unit u-media-1)) + (fr550 (unit u-media))) +) + +; How to extend from a mode to get the intended signedness. +(define-pmacro (DI-ext-HI x) (ext DI x)) +(define-pmacro (DI-ext-UHI x) (zext DI x)) +(define-pmacro (DI-ext-DI x) x) + +(define-pmacro (media-arith-sat-semantics + operation arg1 arg2 res mode max min sie) + (sequence ((DI tmp)) + ; Make sure we saturate at max/min against a value that is + ; sign- or zero-extended appropriately from "mode". + (set tmp (operation DI + ((.sym DI-ext- mode) arg1) ((.sym DI-ext- mode) arg2))) + (saturate-v tmp max min sie res)) +) + +(define-pmacro (media-dual-arith-sat-semantics operation mode max min) + (sequence ((mode argihi) (mode argilo) (mode argjhi) (mode argjlo)) + (extract-hilo FRinti 0 FRintj 0 argihi argilo argjhi argjlo) + (media-arith-sat-semantics operation argihi argjhi + (halfword hi FRintk 0) mode max min + (msr-sie-fri-hi)) + (media-arith-sat-semantics operation argilo argjlo + (halfword lo FRintk 0) mode max min + (msr-sie-fri-lo))) +) + +(define-pmacro (media-dual-arith-sat name operation mode max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-1) (FR550-MAJOR M-2) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + (.str name "$pack $FRinti,$FRintj,$FRintk") + (+ pack FRintk op FRinti ope FRintj) + (media-dual-arith-sat-semantics operation mode max min) + ((fr400 (unit u-media-1)) (fr450 (unit u-media-1)) + (fr500 (unit u-media)) (fr550 (unit u-media))) + ) +) + +(media-dual-arith-sat maddhss add HI 32767 -32768 OP_7B OPE1_10 "Media dual add signed with saturation") +(media-dual-arith-sat maddhus add UHI 65535 0 OP_7B OPE1_11 "Media dual add unsigned with saturation") + +(media-dual-arith-sat msubhss sub HI 32767 -32768 OP_7B OPE1_12 "Media dual sub signed with saturation") +(media-dual-arith-sat msubhus sub UHI 65535 0 OP_7B OPE1_13 "Media dual sub unsigned with saturation") + +(define-pmacro (conditional-media-dual-arith-sat + name operation mode max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-1) (FR550-MAJOR M-2) + (FR400-MAJOR M-1) (FR450-MAJOR M-1) CONDITIONAL) + (.str name "$pack $FRinti,$FRintj,$FRintk,$CCi,$cond") + (+ pack FRintk op FRinti CCi cond ope FRintj) + (if (eq CCi (or cond 2)) + (media-dual-arith-sat-semantics operation mode max min)) + ((fr400 (unit u-media-1)) (fr450 (unit u-media-1)) + (fr500 (unit u-media)) (fr550 (unit u-media))) + ) +) + +(conditional-media-dual-arith-sat cmaddhss add HI 32767 -32768 OP_71 OPE4_0 "Conditional Media dual add signed with saturation") +(conditional-media-dual-arith-sat cmaddhus add UHI 65535 0 OP_71 OPE4_1 "Conditional Media dual add unsigned with saturation") + +(conditional-media-dual-arith-sat cmsubhss sub HI 32767 -32768 OP_71 OPE4_2 "Conditional Media dual sub signed with saturation") +(conditional-media-dual-arith-sat cmsubhus sub UHI 65535 0 OP_71 OPE4_3 "Conditional Media dual sub unsigned with saturation") + +(define-pmacro (media-quad-arith-sat-semantics cond operation mode max min) + (if (orif (register-unaligned FRintieven 2) + (orif (register-unaligned FRintjeven 2) + (register-unaligned FRintkeven 2))) + (c-call VOID "@cpu@_media_register_not_aligned") + (if cond + (sequence ((mode argihi) (mode argilo) (mode argjhi) (mode argjlo)) + ; hack to get FRintkeven referenced as a target for profiling + (set FRintkeven (c-raw-call SI "frv_ref_SI" FRintkeven)) + (extract-hilo FRintieven 0 FRintjeven 0 + argihi argilo argjhi argjlo) + (media-arith-sat-semantics operation argihi argjhi + (halfword hi FRintkeven 0) mode + max min (msr-sie-fri-hi)) + (media-arith-sat-semantics operation argilo argjlo + (halfword lo FRintkeven 0) mode + max min (msr-sie-fri-lo)) + (extract-hilo FRintieven 1 FRintjeven 1 + argihi argilo argjhi argjlo) + (media-arith-sat-semantics operation argihi argjhi + (halfword hi FRintkeven 1) mode + max min (msr-sie-fri-1-hi)) + (media-arith-sat-semantics operation argilo argjlo + (halfword lo FRintkeven 1) mode + max min (msr-sie-fri-1-lo))))) +) + +(define-pmacro (media-quad-arith-sat name operation mode max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-1) (FR550-MAJOR M-2) + (FR400-MAJOR M-2) (FR450-MAJOR M-2)) + (.str name "$pack $FRintieven,$FRintjeven,$FRintkeven") + (+ pack FRintkeven op FRintieven ope FRintjeven) + (media-quad-arith-sat-semantics 1 operation mode max min) + ((fr400 (unit u-media-1-quad + (in FRinti FRintieven) + (in FRintj FRintjeven) + (out FRintk FRintkeven))) + (fr450 (unit u-media-1-quad + (in FRinti FRintieven) + (in FRintj FRintjeven) + (out FRintk FRintkeven))) + (fr500 (unit u-media-quad-arith + (in FRinti FRintieven) + (in FRintj FRintjeven) + (out FRintk FRintkeven))) (fr550 (unit u-media-quad))) + ) +) + +(media-quad-arith-sat mqaddhss add HI 32767 -32768 OP_7B OPE1_18 "Media quad add signed with saturation") +(media-quad-arith-sat mqaddhus add UHI 65535 0 OP_7B OPE1_19 "Media quad add unsigned with saturation") + +(media-quad-arith-sat mqsubhss sub HI 32767 -32768 OP_7B OPE1_1A "Media quad sub signed with saturation") +(media-quad-arith-sat mqsubhus sub UHI 65535 0 OP_7B OPE1_1B "Media quad sub unsigned with saturation") + +(define-pmacro (conditional-media-quad-arith-sat + name operation mode max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-1) (FR550-MAJOR M-2) + (FR400-MAJOR M-2) (FR450-MAJOR M-2) CONDITIONAL) + (.str name "$pack $FRintieven,$FRintjeven,$FRintkeven,$CCi,$cond") + (+ pack FRintkeven op FRintieven CCi cond ope FRintjeven) + (media-quad-arith-sat-semantics (eq CCi (or cond 2)) + operation mode max min) + ((fr400 (unit u-media-1-quad + (in FRinti FRintieven) + (in FRintj FRintjeven) + (out FRintk FRintkeven))) + (fr450 (unit u-media-1-quad + (in FRinti FRintieven) + (in FRintj FRintjeven) + (out FRintk FRintkeven))) + (fr500 (unit u-media-quad-arith + (in FRinti FRintieven) + (in FRintj FRintjeven) + (out FRintk FRintkeven))) (fr550 (unit u-media-quad))) + ) +) + +(conditional-media-quad-arith-sat cmqaddhss add HI 32767 -32768 OP_73 OPE4_0 "Conditional Media quad add signed with saturation") +(conditional-media-quad-arith-sat cmqaddhus add UHI 65535 0 OP_73 OPE4_1 "Conditional Media quad add unsigned with saturation") + +(conditional-media-quad-arith-sat cmqsubhss sub HI 32767 -32768 OP_73 OPE4_2 "Conditional Media quad sub signed with saturation") +(conditional-media-quad-arith-sat cmqsubhus sub UHI 65535 0 OP_73 OPE4_3 "Conditional Media quad sub unsigned with saturation") + +;; Return A if |A| > |B| and B is positive. Return -A if |A| > |B| and +;; B is negative, saturating 0x8000 as 0x7fff. Return 0 otherwise. +(define-pmacro (media-low-clear-semantics a b) + (cond HI + ((le UHI (abs a) (abs b)) 0) + ((le HI 0 b) a) + ((eq HI a -32768) 32767) + (else (neg a)))) + +;; Return A if -|B| < A < |B|. Return -B if A <= -|B|, saturating 0x8000 +;; as 0x7fff. Return B if A >= |B|. +(define-pmacro (media-scope-limit-semantics a b) + (cond HI + ((andif (gt HI b -32768) + (ge HI a (abs b))) b) + ((gt HI a (neg (abs b))) a) + ((eq HI b -32768) 32767) + (else (neg b)))) + +(define-pmacro (media-quad-limit name operation op ope comment) + (dni name + comment + ((UNIT FM0) (MACH fr450) (FR450-MAJOR M-2)) + (.str name "$pack $FRintieven,$FRintjeven,$FRintkeven") + (+ pack FRintkeven op FRintieven ope FRintjeven) + (if (orif (register-unaligned FRintieven 2) + (orif (register-unaligned FRintjeven 2) + (register-unaligned FRintkeven 2))) + (c-call VOID "@cpu@_media_register_not_aligned") + (sequence ((HI a1) (HI a2) (HI a3) (HI a4) + (HI b1) (HI b2) (HI b3) (HI b4)) + ; hack to get FRintkeven referenced as a target + ; for profiling + (set FRintkeven (c-raw-call SI "frv_ref_SI" FRintkeven)) + (extract-hilo FRintieven 0 FRintjeven 0 a1 a2 b1 b2) + (extract-hilo FRintieven 1 FRintjeven 1 a3 a4 b3 b4) + (set (halfword hi FRintkeven 0) (operation a1 b1)) + (set (halfword lo FRintkeven 0) (operation a2 b2)) + (set (halfword hi FRintkeven 1) (operation a3 b3)) + (set (halfword lo FRintkeven 1) (operation a4 b4)))) + ((fr450 (unit u-media-1-quad + (in FRinti FRintieven) + (in FRintj FRintjeven) + (out FRintk FRintkeven)))) + ) +) + +(media-quad-limit mqlclrhs media-low-clear-semantics OP_78 OPE1_10 + "Media quad low clear") +(media-quad-limit mqlmths media-scope-limit-semantics OP_78 OPE1_14 + "Media quad scope limitation") + +(define-pmacro (media-quad-shift name operation op ope comment) + (dni name + (comment) + ((UNIT FM0) (MACH fr450) (FR450-MAJOR M-2)) + (.str name "$pack $FRintieven,$u6,$FRintkeven") + (+ pack FRintkeven op FRintieven ope u6) + (if (orif (register-unaligned FRintieven 2) + (register-unaligned FRintkeven 2)) + (c-call VOID "@cpu@_media_register_not_aligned") + (sequence () + ; hack to get these referenced for profiling + (set FRintieven (c-raw-call SI "frv_ref_SI" FRintieven)) + (set FRintkeven (c-raw-call SI "frv_ref_SI" FRintkeven)) + (set (halfword hi FRintkeven 0) + (operation HI (halfword hi FRintieven 0) + (and u6 #xf))) + (set (halfword lo FRintkeven 0) + (operation HI (halfword lo FRintieven 0) + (and u6 #xf))) + (set (halfword hi FRintkeven 1) + (operation HI (halfword hi FRintieven 1) + (and u6 #xf))) + (set (halfword lo FRintkeven 1) + (operation HI (halfword lo FRintieven 1) + (and u6 #xf))))) + ((fr450 (unit u-media-3-quad + (in FRinti FRintieven) + (in FRintj FRintieven) + (out FRintk FRintkeven)))) + ) +) + +(media-quad-shift mqsllhi sll OP_78 OPE1_11 "Media quad left shift") +(media-quad-shift mqsrahi sra OP_78 OPE1_13 "Media quad right shift") + +(define-pmacro (media-acc-arith-sat name operation mode max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (MACH fr400,fr450,fr550) (FR550-MAJOR M-4) + (FR400-MAJOR M-1) (FR450-MAJOR M-3)) + (.str name "$pack $ACC40Si,$ACC40Sk") + (+ pack ACC40Sk op ACC40Si ope (ACCj-null)) + (if (c-call SI "@cpu@_check_acc_range" (index-of ACC40Si)) + (if (c-call SI "@cpu@_check_acc_range" (index-of ACC40Sk)) + (if (register-unaligned ACC40Si 2) + (c-call VOID "@cpu@_media_acc_not_aligned") + (media-arith-sat-semantics operation ACC40Si + (nextreg h-acc40S ACC40Si 1) + ACC40Sk mode max min (msr-sie-acci))))) + ((fr400 (unit u-media-2-acc)) (fr450 (unit u-media-2-acc)) + (fr550 (unit u-media-4-acc))) + ) +) + +(media-acc-arith-sat maddaccs add DI #x7fffffffff (inv DI #x7fffffffff) + OP_78 OPE1_04 "Media accumulator addition") +(media-acc-arith-sat msubaccs sub DI #x7fffffffff (inv DI #x7fffffffff) + OP_78 OPE1_05 "Media accumulator subtraction") + +(define-pmacro (media-dual-acc-arith-sat name operation mode max min op ope + comment) + (dni name + (comment) + ((UNIT MDUALACC) (MACH fr400,fr450,fr550) (FR550-MAJOR M-4) + (FR400-MAJOR M-2) (FR450-MAJOR M-4)) + (.str name "$pack $ACC40Si,$ACC40Sk") + (+ pack ACC40Sk op ACC40Si ope (ACCj-null)) + (if (c-call SI "@cpu@_check_acc_range" (index-of ACC40Si)) + (if (c-call SI "@cpu@_check_acc_range" (index-of ACC40Sk)) + (if (register-unaligned ACC40Si 4) + (c-call VOID "@cpu@_media_acc_not_aligned") + (if (register-unaligned ACC40Sk 2) + (c-call VOID "@cpu@_media_acc_not_aligned") + (sequence () + (media-arith-sat-semantics operation ACC40Si + (nextreg h-acc40S ACC40Si 1) + ACC40Sk mode max min + (msr-sie-acci)) + (media-arith-sat-semantics operation + (nextreg h-acc40S ACC40Si 2) + (nextreg h-acc40S ACC40Si 3) + (nextreg h-acc40S ACC40Sk 1) + mode max min + (msr-sie-acci-1))))))) + ((fr400 (unit u-media-2-acc-dual)) (fr450 (unit u-media-2-acc-dual)) + (fr550 (unit u-media-4-acc-dual))) + ) +) + +(media-dual-acc-arith-sat mdaddaccs add DI #x7fffffffff (inv DI #x7fffffffff) + OP_78 OPE1_06 "Media accumulator addition") +(media-dual-acc-arith-sat mdsubaccs sub DI #x7fffffffff (inv DI #x7fffffffff) + OP_78 OPE1_07 "Media accumulator subtraction") + +(dni masaccs + "Media add and subtract signed accumulator with saturation" + ((UNIT FMALL) (MACH fr400,fr450,fr550) (FR550-MAJOR M-4) + (FR400-MAJOR M-1) (FR450-MAJOR M-3)) + "masaccs$pack $ACC40Si,$ACC40Sk" + (+ pack ACC40Sk OP_78 ACC40Si OPE1_08 (ACCj-null)) + (if (c-call SI "@cpu@_check_acc_range" (index-of ACC40Si)) + (if (c-call SI "@cpu@_check_acc_range" (index-of ACC40Sk)) + (if (register-unaligned ACC40Si 2) + (c-call VOID "@cpu@_media_acc_not_aligned") + (if (register-unaligned ACC40Sk 2) + (c-call VOID "@cpu@_media_acc_not_aligned") + (sequence () + (media-arith-sat-semantics add ACC40Si + (nextreg h-acc40S ACC40Si 1) + ACC40Sk DI + #x7fffffffff + (inv DI #x7fffffffff) + (msr-sie-acci)) + (media-arith-sat-semantics sub ACC40Si + (nextreg h-acc40S ACC40Si 1) + (nextreg h-acc40S ACC40Sk 1) + DI + #x7fffffffff + (inv DI #x7fffffffff) + (msr-sie-acci-1))))))) + ((fr400 (unit u-media-2-add-sub)) (fr450 (unit u-media-2-add-sub)) + (fr550 (unit u-media-4-add-sub))) + ) + +(dni mdasaccs + "Media add and subtract signed accumulator with saturation" + ((UNIT MDUALACC) (MACH fr400,fr450,fr550) (FR550-MAJOR M-4) + (FR400-MAJOR M-2) (FR450-MAJOR M-4)) + "mdasaccs$pack $ACC40Si,$ACC40Sk" + (+ pack ACC40Sk OP_78 ACC40Si OPE1_09 (ACCj-null)) + (if (c-call SI "@cpu@_check_acc_range" (index-of ACC40Si)) + (if (c-call SI "@cpu@_check_acc_range" (index-of ACC40Sk)) + (if (register-unaligned ACC40Si 4) + (c-call VOID "@cpu@_media_acc_not_aligned") + (if (register-unaligned ACC40Sk 4) + (c-call VOID "@cpu@_media_acc_not_aligned") + (sequence () + (media-arith-sat-semantics add ACC40Si + (nextreg h-acc40S ACC40Si 1) + ACC40Sk DI + #x7fffffffff + (inv DI #x7fffffffff) + (msr-sie-acci)) + (media-arith-sat-semantics sub ACC40Si + (nextreg h-acc40S ACC40Si 1) + (nextreg h-acc40S ACC40Sk 1) + DI + #x7fffffffff + (inv DI #x7fffffffff) + (msr-sie-acci-1)) + (media-arith-sat-semantics add + (nextreg h-acc40S ACC40Si 2) + (nextreg h-acc40S ACC40Si 3) + (nextreg h-acc40S ACC40Sk 2) + DI + #x7fffffffff + (inv DI #x7fffffffff) + (msr-sie-acci-2)) + (media-arith-sat-semantics sub + (nextreg h-acc40S ACC40Si 2) + (nextreg h-acc40S ACC40Si 3) + (nextreg h-acc40S ACC40Sk 3) + DI + #x7fffffffff + (inv DI #x7fffffffff) + (msr-sie-acci-3))))))) + ((fr400 (unit u-media-2-add-sub-dual)) + (fr450 (unit u-media-2-add-sub-dual)) + (fr550 (unit u-media-4-add-sub-dual))) + ) + +(define-pmacro (media-multiply-semantics conv arg1 arg2 res) + (set res (mul DI (conv DI arg1) (conv DI arg2))) +) + +(define-pmacro (media-dual-multiply-semantics cond mode conv rhs1 rhs2) + (if (c-call SI "@cpu@_check_acc_range" (index-of ACC40Sk)) + (if (register-unaligned ACC40Sk 2) + (c-call VOID "@cpu@_media_acc_not_aligned") + (if cond + (sequence ((mode argihi) (mode argilo) (mode argjhi) (mode argjlo)) + (extract-hilo FRinti 0 FRintj 0 + argihi argilo argjhi argjlo) + (media-multiply-semantics conv argihi rhs1 ACC40Sk) + (media-multiply-semantics conv argilo rhs2 + (nextreg h-acc40S ACC40Sk 1)))))) +) + +(define-pmacro (media-dual-multiply name mode conv rhs1 rhs2 op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-4) (FR550-MAJOR M-4) + (FR400-MAJOR M-1) (FR450-MAJOR M-3) PRESERVE-OVF) + (.str name "$pack $FRinti,$FRintj,$ACC40Sk") + (+ pack ACC40Sk op FRinti ope FRintj) + (media-dual-multiply-semantics 1 mode conv rhs1 rhs2) + ((fr400 (unit u-media-2)) (fr450 (unit u-media-2)) + (fr500 (unit u-media-dual-mul)) (fr550 (unit u-media-4))) + ) +) + +(media-dual-multiply mmulhs HI ext argjhi argjlo OP_7B OPE1_14 "Media dual multiply signed") +(media-dual-multiply mmulhu UHI zext argjhi argjlo OP_7B OPE1_15 "Media dual multiply unsigned") + +(media-dual-multiply mmulxhs HI ext argjlo argjhi OP_7B OPE1_28 "Media dual cross multiply signed") +(media-dual-multiply mmulxhu UHI zext argjlo argjhi OP_7B OPE1_29 "Media dual cross multiply unsigned") + +(define-pmacro (conditional-media-dual-multiply + name mode conv rhs1 rhs2 op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-4) (FR550-MAJOR M-4) + (FR400-MAJOR M-1) (FR450-MAJOR M-3) + PRESERVE-OVF CONDITIONAL) + (.str name "$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond") + (+ pack ACC40Sk op FRinti CCi cond ope FRintj) + (media-dual-multiply-semantics (eq CCi (or cond 2)) mode conv rhs1 rhs2) + ((fr400 (unit u-media-2)) (fr450 (unit u-media-2)) + (fr500 (unit u-media-dual-mul)) (fr550 (unit u-media-4))) + ) +) + +(conditional-media-dual-multiply cmmulhs HI ext argjhi argjlo OP_72 OPE4_0 "Conditional Media dual multiply signed") +(conditional-media-dual-multiply cmmulhu UHI zext argjhi argjlo OP_72 OPE4_1 "Conditional Media dual multiply unsigned") + +(define-pmacro (media-quad-multiply-semantics cond mode conv rhs1 rhs2) + (if (c-call SI "@cpu@_check_acc_range" (index-of ACC40Sk)) + (if (register-unaligned ACC40Sk 4) + (c-call VOID "@cpu@_media_acc_not_aligned") + (if (orif (register-unaligned FRintieven 2) + (register-unaligned FRintjeven 2)) + (c-call VOID "@cpu@_media_register_not_aligned") + (if cond + (sequence ((mode argihi) (mode argilo) + (mode argjhi) (mode argjlo)) + (extract-hilo FRintieven 0 FRintjeven 0 + argihi argilo argjhi argjlo) + (media-multiply-semantics conv argihi rhs1 ACC40Sk) + (media-multiply-semantics conv argilo rhs2 + (nextreg h-acc40S ACC40Sk 1)) + (extract-hilo FRintieven 1 FRintjeven 1 + argihi argilo argjhi argjlo) + (media-multiply-semantics conv argihi rhs1 + (nextreg h-acc40S ACC40Sk 2)) + (media-multiply-semantics conv argilo rhs2 + (nextreg h-acc40S ACC40Sk 3))))))) +) + +(define-pmacro (media-quad-multiply name mode conv rhs1 rhs2 op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-4) (FR550-MAJOR M-4) + (FR400-MAJOR M-2) (FR450-MAJOR M-4) PRESERVE-OVF) + (.str name "$pack $FRintieven,$FRintjeven,$ACC40Sk") + (+ pack ACC40Sk op FRintieven ope FRintjeven) + (media-quad-multiply-semantics 1 mode conv rhs1 rhs2) + ((fr400 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr450 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr500 (unit u-media-quad-mul + (in FRinti FRintieven) + (in FRintj FRintjeven))) (fr550 (unit u-media-4-quad))) + ) +) + +(media-quad-multiply mqmulhs HI ext argjhi argjlo OP_7B OPE1_1C "Media quad multiply signed") +(media-quad-multiply mqmulhu UHI zext argjhi argjlo OP_7B OPE1_1D "Media quad multiply unsigned") + +(media-quad-multiply mqmulxhs HI ext argjlo argjhi OP_7B OPE1_2A "Media quad cross multiply signed") +(media-quad-multiply mqmulxhu UHI zext argjlo argjhi OP_7B OPE1_2B "Media quad cross multiply unsigned") + +(define-pmacro (conditional-media-quad-multiply + name mode conv rhs1 rhs2 op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-4) (FR550-MAJOR M-4) + (FR400-MAJOR M-2) (FR450-MAJOR M-4) + PRESERVE-OVF CONDITIONAL) + (.str name "$pack $FRintieven,$FRintjeven,$ACC40Sk,$CCi,$cond") + (+ pack ACC40Sk op FRintieven CCi cond ope FRintjeven) + (media-quad-multiply-semantics (eq CCi (or cond 2)) mode conv rhs1 rhs2) + ((fr400 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr450 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr500 (unit u-media-quad-mul + (in FRinti FRintieven) + (in FRintj FRintjeven))) (fr550 (unit u-media-4-quad))) + ) +) + +(conditional-media-quad-multiply cmqmulhs HI ext argjhi argjlo OP_74 OPE4_0 "Conditional Media quad multiply signed") +(conditional-media-quad-multiply cmqmulhu UHI zext argjhi argjlo OP_74 OPE4_1 "Conditional Media quad multiply unsigned") + +(define-pmacro (media-multiply-acc-semantics + conv arg1 addop arg2 res max min sie) + (sequence ((DI tmp)) + (set tmp (addop res (mul DI (conv DI arg1) (conv DI arg2)))) + (saturate-v tmp max min sie res)) +) + +(define-pmacro (media-dual-multiply-acc-semantics + cond mode conv addop rhw res max min) + (if (c-call SI "@cpu@_check_acc_range" (index-of res)) + (if (register-unaligned res 2) + (c-call VOID "@cpu@_media_acc_not_aligned") + (if cond + (sequence ((mode argihi) (mode argilo) (mode argjhi) (mode argjlo)) + (extract-hilo FRinti 0 FRintj 0 + argihi argilo argjhi argjlo) + (media-multiply-acc-semantics conv argihi addop argjhi + res + max min (msr-sie-acci)) + (media-multiply-acc-semantics conv argilo addop argjlo + (nextreg rhw res 1) + max min (msr-sie-acci-1)))))) +) + +(define-pmacro (media-dual-multiply-acc + name mode conv addop rhw res max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-4) (FR550-MAJOR M-4) + (FR400-MAJOR M-1) (FR450-MAJOR M-3)) + (.str name "$pack $FRinti,$FRintj,$" res) + (+ pack res op FRinti ope FRintj) + (media-dual-multiply-acc-semantics 1 mode conv addop rhw res max min) + ((fr400 (unit u-media-2)) (fr450 (unit u-media-2)) + (fr500 (unit u-media-dual-mul)) (fr550 (unit u-media-4))) + ) +) + +(media-dual-multiply-acc mmachs HI ext add h-acc40S ACC40Sk + (const DI #x7fffffffff) (const DI #xffffff8000000000) + OP_7B OPE1_16 + "Media dual multiply and accumulate signed") + +(media-dual-multiply-acc mmachu UHI zext add h-acc40U ACC40Uk + (const DI #xffffffffff) (const DI 0) + OP_7B OPE1_17 + "Media dual multiply and accumulate unsigned") + +(media-dual-multiply-acc mmrdhs HI ext sub h-acc40S ACC40Sk + (const DI #x7fffffffff) (const DI #xffffff8000000000) + OP_7B OPE1_30 + "Media dual multiply and reduce signed") + +(media-dual-multiply-acc mmrdhu UHI zext sub h-acc40U ACC40Uk + (const DI #xffffffffff) (const DI 0) + OP_7B OPE1_31 + "Media dual multiply and reduce unsigned") + +(define-pmacro (conditional-media-dual-multiply-acc + name mode conv addop rhw res max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-4) (FR550-MAJOR M-4) + (FR400-MAJOR M-1) (FR450-MAJOR M-3) CONDITIONAL) + (.str name "$pack $FRinti,$FRintj,$" res ",$CCi,$cond") + (+ pack res op FRinti CCi cond ope FRintj) + (media-dual-multiply-acc-semantics (eq CCi (or cond 2)) + mode conv addop rhw res max min) + ((fr400 (unit u-media-2)) (fr450 (unit u-media-2)) + (fr500 (unit u-media-dual-mul)) (fr550 (unit u-media-4))) + ) +) + +(conditional-media-dual-multiply-acc cmmachs HI ext add h-acc40S ACC40Sk + (const DI #x7fffffffff) (const DI #xffffff8000000000) + OP_72 OPE4_2 + "Conditional Media dual multiply and accumulate signed") + +(conditional-media-dual-multiply-acc cmmachu UHI zext add h-acc40U ACC40Uk + (const DI #xffffffffff) (const DI 0) + OP_72 OPE4_3 + "Conditional Media dual multiply and accumulate unsigned") + +(define-pmacro (media-quad-multiply-acc-semantics + cond mode conv addop rhw res max min) + (if (c-call SI "@cpu@_check_acc_range" (index-of res)) + (if (register-unaligned res 4) + (c-call VOID "@cpu@_media_acc_not_aligned") + (if (orif (register-unaligned FRintieven 2) + (register-unaligned FRintjeven 2)) + (c-call VOID "@cpu@_media_register_not_aligned") + (if cond + (sequence ((mode argihi) (mode argilo) + (mode argjhi) (mode argjlo)) + (extract-hilo FRintieven 0 FRintjeven 0 + argihi argilo argjhi argjlo) + (media-multiply-acc-semantics conv argihi addop argjhi + res + max min (msr-sie-acci)) + (media-multiply-acc-semantics conv argilo addop argjlo + (nextreg rhw res 1) + max min (msr-sie-acci-1)) + (extract-hilo FRintieven 1 FRintjeven 1 + argihi argilo argjhi argjlo) + (media-multiply-acc-semantics conv argihi addop argjhi + (nextreg rhw res 2) + max min (msr-sie-acci-2)) + (media-multiply-acc-semantics conv argilo addop argjlo + (nextreg rhw res 3) + max min + (msr-sie-acci-3))))))) +) + +(define-pmacro (media-quad-multiply-acc + name mode conv addop rhw res max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-4) (FR550-MAJOR M-4) + (FR400-MAJOR M-2) (FR450-MAJOR M-4)) + (.str name "$pack $FRintieven,$FRintjeven,$" res) + (+ pack res op FRintieven ope FRintjeven) + (media-quad-multiply-acc-semantics 1 mode conv addop rhw res max min) + ((fr400 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr450 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr500 (unit u-media-quad-mul + (in FRinti FRintieven) + (in FRintj FRintjeven))) (fr550 (unit u-media-4-quad))) + ) +) + +(media-quad-multiply-acc mqmachs HI ext add h-acc40S ACC40Sk + (const DI #x7fffffffff) (const DI #xffffff8000000000) + OP_7B OPE1_1E + "Media quad multiply and accumulate signed") + +(media-quad-multiply-acc mqmachu UHI zext add h-acc40U ACC40Uk + (const DI #xffffffffff) (const DI 0) + OP_7B OPE1_1F + "Media quad multiply and accumulate unsigned") + +(define-pmacro (conditional-media-quad-multiply-acc + name mode conv addop rhw res max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-4) (FR550-MAJOR M-4) + (FR400-MAJOR M-2) (FR450-MAJOR M-4) CONDITIONAL) + (.str name "$pack $FRintieven,$FRintjeven,$" res ",$CCi,$cond") + (+ pack res op FRintieven CCi cond ope FRintjeven) + (media-quad-multiply-acc-semantics (eq CCi (or cond 2)) + mode conv addop rhw res max min) + ((fr400 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr450 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr500 (unit u-media-quad-mul + (in FRinti FRintieven) + (in FRintj FRintjeven))) (fr550 (unit u-media-4-quad))) + ) +) + +(conditional-media-quad-multiply-acc cmqmachs HI ext add h-acc40S ACC40Sk + (const DI #x7fffffffff) (const DI #xffffff8000000000) + OP_74 OPE4_2 + "Conditional Media quad multiply and accumulate signed") + +(conditional-media-quad-multiply-acc cmqmachu UHI zext add h-acc40U ACC40Uk + (const DI #xffffffffff) (const DI 0) + OP_74 OPE4_3 + "Conditional media quad multiply and accumulate unsigned") + +(define-pmacro (media-quad-multiply-cross-acc-semantics + cond mode conv addop rhw res max min) + (if (c-call SI "@cpu@_check_acc_range" (index-of res)) + (if (register-unaligned res 4) + (c-call VOID "@cpu@_media_acc_not_aligned") + (if (orif (register-unaligned FRintieven 2) + (register-unaligned FRintjeven 2)) + (c-call VOID "@cpu@_media_register_not_aligned") + (if cond + (sequence ((mode argihi) (mode argilo) + (mode argjhi) (mode argjlo)) + (extract-hilo FRintieven 0 FRintjeven 0 + argihi argilo argjhi argjlo) + (media-multiply-acc-semantics conv argihi addop argjhi + (nextreg rhw res 2) + max min (msr-sie-acci-2)) + (media-multiply-acc-semantics conv argilo addop argjlo + (nextreg rhw res 3) + max min (msr-sie-acci-3)) + (extract-hilo FRintieven 1 FRintjeven 1 + argihi argilo argjhi argjlo) + (media-multiply-acc-semantics conv argihi addop argjhi + res + max min (msr-sie-acci)) + (media-multiply-acc-semantics conv argilo addop argjlo + (nextreg rhw res 1) + max min + (msr-sie-acci-1))))))) +) + +(define-pmacro (media-quad-multiply-cross-acc + name mode conv addop rhw res max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (MACH fr400,fr450,fr550) (FR550-MAJOR M-4) + (FR400-MAJOR M-2) (FR450-MAJOR M-4)) + (.str name "$pack $FRintieven,$FRintjeven,$" res) + (+ pack res op FRintieven ope FRintjeven) + (media-quad-multiply-cross-acc-semantics 1 mode conv addop rhw res + max min) + ((fr400 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr450 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr550 (unit u-media-4-quad))) + ) +) + +(media-quad-multiply-cross-acc mqxmachs HI ext add h-acc40S ACC40Sk + (const DI #x7fffffffff) (const DI #xffffff8000000000) + OP_78 OPE1_00 + "Media quad multiply and cross accumulate signed") + +(define-pmacro (media-quad-cross-multiply-cross-acc-semantics + cond mode conv addop rhw res max min) + (if (c-call SI "@cpu@_check_acc_range" (index-of res)) + (if (register-unaligned res 4) + (c-call VOID "@cpu@_media_acc_not_aligned") + (if (orif (register-unaligned FRintieven 2) + (register-unaligned FRintjeven 2)) + (c-call VOID "@cpu@_media_register_not_aligned") + (if cond + (sequence ((mode argihi) (mode argilo) + (mode argjhi) (mode argjlo)) + (extract-hilo FRintieven 0 FRintjeven 0 + argihi argilo argjhi argjlo) + (media-multiply-acc-semantics conv argihi addop argjlo + (nextreg rhw res 2) + max min (msr-sie-acci-2)) + (media-multiply-acc-semantics conv argilo addop argjhi + (nextreg rhw res 3) + max min (msr-sie-acci-3)) + (extract-hilo FRintieven 1 FRintjeven 1 + argihi argilo argjhi argjlo) + (media-multiply-acc-semantics conv argihi addop argjlo + res + max min (msr-sie-acci)) + (media-multiply-acc-semantics conv argilo addop argjhi + (nextreg rhw res 1) + max min + (msr-sie-acci-1))))))) +) + +(define-pmacro (media-quad-cross-multiply-cross-acc + name mode conv addop rhw res max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (MACH fr400,fr450,fr550) (FR550-MAJOR M-4) + (FR400-MAJOR M-2) (FR450-MAJOR M-4)) + (.str name "$pack $FRintieven,$FRintjeven,$" res) + (+ pack res op FRintieven ope FRintjeven) + (media-quad-cross-multiply-cross-acc-semantics 1 mode conv addop rhw res + max min) + ((fr400 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr450 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr550 (unit u-media-4-quad))) + ) +) + +(media-quad-cross-multiply-cross-acc mqxmacxhs HI ext add h-acc40S ACC40Sk + (const DI #x7fffffffff) (const DI #xffffff8000000000) + OP_78 OPE1_01 + "Media quad cross multiply and cross accumulate signed") + +(define-pmacro (media-quad-cross-multiply-acc-semantics + cond mode conv addop rhw res max min) + (if (c-call SI "@cpu@_check_acc_range" (index-of res)) + (if (register-unaligned res 4) + (c-call VOID "@cpu@_media_acc_not_aligned") + (if (orif (register-unaligned FRintieven 2) + (register-unaligned FRintjeven 2)) + (c-call VOID "@cpu@_media_register_not_aligned") + (if cond + (sequence ((mode argihi) (mode argilo) + (mode argjhi) (mode argjlo)) + (extract-hilo FRintieven 0 FRintjeven 0 + argihi argilo argjhi argjlo) + (media-multiply-acc-semantics conv argihi addop argjlo + res + max min (msr-sie-acci)) + (media-multiply-acc-semantics conv argilo addop argjhi + (nextreg rhw res 1) + max min (msr-sie-acci-1)) + (extract-hilo FRintieven 1 FRintjeven 1 + argihi argilo argjhi argjlo) + (media-multiply-acc-semantics conv argihi addop argjlo + (nextreg rhw res 2) + max min (msr-sie-acci-2)) + (media-multiply-acc-semantics conv argilo addop argjhi + (nextreg rhw res 3) + max min + (msr-sie-acci-3))))))) +) + +(define-pmacro (media-quad-cross-multiply-acc + name mode conv addop rhw res max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (MACH fr400,fr450,fr550) (FR550-MAJOR M-4) + (FR400-MAJOR M-2) (FR450-MAJOR M-4)) + (.str name "$pack $FRintieven,$FRintjeven,$" res) + (+ pack res op FRintieven ope FRintjeven) + (media-quad-cross-multiply-acc-semantics 1 mode conv addop rhw res + max min) + ((fr400 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr450 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr550 (unit u-media-4-quad))) + ) +) + +(media-quad-cross-multiply-acc mqmacxhs HI ext add h-acc40S ACC40Sk + (const DI #x7fffffffff) (const DI #xffffff8000000000) + OP_78 OPE1_02 + "Media quad cross multiply and accumulate signed") + +(define-pmacro (media-complex-semantics + conv lhs1 rhs1 lhs2 rhs2 res max min sie) + (sequence ((DI tmp1) (DI tmp2)) + (media-multiply-semantics conv lhs1 rhs1 tmp1) + (media-multiply-semantics conv lhs2 rhs2 tmp2) + (set tmp1 (sub tmp1 tmp2)) + (saturate-v tmp1 max min sie res)) +) + +(define-pmacro (media-complex-semantics-i + conv lhs1 rhs1 lhs2 rhs2 res max min sie) + (sequence ((DI tmp1) (DI tmp2)) + (media-multiply-semantics conv lhs1 rhs1 tmp1) + (media-multiply-semantics conv lhs2 rhs2 tmp2) + (set tmp1 (add tmp1 tmp2)) + (saturate-v tmp1 max min sie res)) +) + +(define-pmacro (media-dual-complex-semantics mode conv rhs1 rhs2 max min) + (if (c-call SI "@cpu@_check_acc_range" (index-of ACC40Sk)) + (sequence ((mode argihi) (mode argilo) (mode argjhi) (mode argjlo)) + (extract-hilo FRinti 0 FRintj 0 argihi argilo argjhi argjlo) + (media-complex-semantics conv argihi rhs1 argilo rhs2 ACC40Sk + max min (msr-sie-acci)))) +) + +(define-pmacro (media-dual-complex-semantics-i mode conv rhs1 rhs2 max min) + (if (c-call SI "@cpu@_check_acc_range" (index-of ACC40Sk)) + (sequence ((mode argihi) (mode argilo) (mode argjhi) (mode argjlo)) + (extract-hilo FRinti 0 FRintj 0 argihi argilo argjhi argjlo) + (media-complex-semantics-i conv argihi rhs1 argilo rhs2 ACC40Sk + max min (msr-sie-acci)))) +) + +(define-pmacro (media-dual-complex + name mode conv rhs1 rhs2 max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-4) (FR550-MAJOR M-4) + (FR400-MAJOR M-1) (FR450-MAJOR M-3)) + (.str name "$pack $FRinti,$FRintj,$ACC40Sk") + (+ pack ACC40Sk op FRinti ope FRintj) + (media-dual-complex-semantics mode conv rhs1 rhs2 max min) + ((fr400 (unit u-media-2)) (fr450 (unit u-media-2)) + (fr500 (unit u-media-dual-mul)) (fr550 (unit u-media-4))) + ) +) + +(define-pmacro (media-dual-complex-i + name mode conv rhs1 rhs2 max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-4) (FR550-MAJOR M-4) + (FR400-MAJOR M-1) (FR450-MAJOR M-3)) + (.str name "$pack $FRinti,$FRintj,$ACC40Sk") + (+ pack ACC40Sk op FRinti ope FRintj) + (media-dual-complex-semantics-i mode conv rhs1 rhs2 max min) + ((fr400 (unit u-media-2)) (fr450 (unit u-media-2)) + (fr500 (unit u-media-dual-mul)) (fr550 (unit u-media-4))) + ) +) + +(media-dual-complex mcpxrs HI ext argjhi argjlo + (const DI #x7fffffffff) (const DI #xffffff8000000000) + OP_7B OPE1_20 + "Media dual complex real signed with saturation") + +(media-dual-complex mcpxru UHI zext argjhi argjlo + (const DI #xffffffffff) (const DI 0) + OP_7B OPE1_21 + "Media dual complex real unsigned with saturation") + +(media-dual-complex-i mcpxis HI ext argjlo argjhi + (const DI #x7fffffffff) (const DI #xffffff8000000000) + OP_7B OPE1_22 + "Media dual complex imaginary signed with saturation") + +(media-dual-complex-i mcpxiu UHI zext argjlo argjhi + (const DI #xffffffffff) (const DI 0) + OP_7B OPE1_23 + "Media dual complex imaginary unsigned with saturation") + +(define-pmacro (conditional-media-dual-complex + name mode conv rhs1 rhs2 max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-4) (FR550-MAJOR M-4) + (FR400-MAJOR M-1) (FR450-MAJOR M-3) CONDITIONAL) + (.str name "$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond") + (+ pack ACC40Sk op FRinti CCi cond ope FRintj) + (if (eq CCi (or cond 2)) + (media-dual-complex-semantics mode conv rhs1 rhs2 max min)) + ((fr400 (unit u-media-2)) (fr450 (unit u-media-2)) + (fr500 (unit u-media-dual-mul)) (fr550 (unit u-media-4))) + ) +) + +(define-pmacro (conditional-media-dual-complex-i + name mode conv rhs1 rhs2 max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-4) (FR550-MAJOR M-4) + (FR400-MAJOR M-1) (FR450-MAJOR M-3) CONDITIONAL) + (.str name "$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond") + (+ pack ACC40Sk op FRinti CCi cond ope FRintj) + (if (eq CCi (or cond 2)) + (media-dual-complex-semantics-i mode conv rhs1 rhs2 max min)) + ((fr400 (unit u-media-2)) (fr450 (unit u-media-2)) + (fr500 (unit u-media-dual-mul)) (fr550 (unit u-media-4))) + ) +) + +(conditional-media-dual-complex cmcpxrs HI ext argjhi argjlo + (const DI #x7fffffffff) (const DI #xffffff8000000000) + OP_75 OPE4_0 + "Conditional Media dual complex real signed with saturation") + +(conditional-media-dual-complex cmcpxru UHI zext argjhi argjlo + (const DI #xffffffffff) (const DI 0) + OP_75 OPE4_1 + "Conditional Media dual complex real unsigned with saturation") + +(conditional-media-dual-complex-i cmcpxis HI ext argjlo argjhi + (const DI #x7fffffffff) (const DI #xffffff8000000000) + OP_75 OPE4_2 + "Conditional Media dual complex imaginary signed with saturation") + +(conditional-media-dual-complex-i cmcpxiu UHI zext argjlo argjhi + (const DI #xffffffffff) (const DI 0) + OP_75 OPE4_3 + "Conditional Media dual complex imaginary unsigned with saturation") + +(define-pmacro (media-quad-complex + name mode conv rhs1 rhs2 max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-4) (FR550-MAJOR M-4) + (FR400-MAJOR M-2) (FR450-MAJOR M-4)) + (.str name "$pack $FRintieven,$FRintjeven,$ACC40Sk") + (+ pack ACC40Sk op FRintieven ope FRintjeven) + (if (c-call SI "@cpu@_check_acc_range" (index-of ACC40Sk)) + (if (register-unaligned ACC40Sk 2) + (c-call VOID "@cpu@_media_acc_not_aligned") + (if (orif (register-unaligned FRintieven 2) + (register-unaligned FRintjeven 2)) + (c-call VOID "@cpu@_media_register_not_aligned") + (sequence ((mode argihi) (mode argilo) + (mode argjhi) (mode argjlo)) + (extract-hilo FRintieven 0 FRintjeven 0 + argihi argilo argjhi argjlo) + (media-complex-semantics conv argihi rhs1 argilo rhs2 + ACC40Sk + max min (msr-sie-acci)) + (extract-hilo FRintieven 1 FRintjeven 1 + argihi argilo argjhi argjlo) + (media-complex-semantics conv argihi rhs1 argilo rhs2 + (nextreg h-acc40S ACC40Sk 1) + max min (msr-sie-acci-1)))))) + ((fr400 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr450 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr500 (unit u-media-quad-complex + (in FRinti FRintieven) + (in FRintj FRintjeven))) (fr550 (unit u-media-4-quad))) + ) +) + +(define-pmacro (media-quad-complex-i + name mode conv rhs1 rhs2 max min op ope comment) + (dni name + (comment) + ((UNIT FMALL) (FR500-MAJOR M-4) (FR550-MAJOR M-4) + (FR400-MAJOR M-2) (FR450-MAJOR M-4)) + (.str name "$pack $FRintieven,$FRintjeven,$ACC40Sk") + (+ pack ACC40Sk op FRintieven ope FRintjeven) + (if (c-call SI "@cpu@_check_acc_range" (index-of ACC40Sk)) + (if (register-unaligned ACC40Sk 2) + (c-call VOID "@cpu@_media_acc_not_aligned") + (if (orif (register-unaligned FRintieven 2) + (register-unaligned FRintjeven 2)) + (c-call VOID "@cpu@_media_register_not_aligned") + (sequence ((mode argihi) (mode argilo) + (mode argjhi) (mode argjlo)) + (extract-hilo FRintieven 0 FRintjeven 0 + argihi argilo argjhi argjlo) + (media-complex-semantics-i conv argihi rhs1 argilo rhs2 + ACC40Sk + max min (msr-sie-acci)) + (extract-hilo FRintieven 1 FRintjeven 1 + argihi argilo argjhi argjlo) + (media-complex-semantics-i conv argihi rhs1 argilo rhs2 + (nextreg h-acc40S ACC40Sk 1) + max min (msr-sie-acci-1)))))) + ((fr400 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr450 (unit u-media-2-quad + (in FRinti FRintieven) + (in FRintj FRintjeven))) + (fr500 (unit u-media-quad-complex + (in FRinti FRintieven) + (in FRintj FRintjeven))) (fr550 (unit u-media-4-quad))) + ) +) + +(media-quad-complex mqcpxrs HI ext argjhi argjlo + (const DI #x7fffffffff) (const DI #xffffff8000000000) + OP_7B OPE1_24 + "Media quad complex real signed with saturation") + +(media-quad-complex mqcpxru UHI zext argjhi argjlo + (const DI #xffffffffff) (const DI 0) + OP_7B OPE1_25 + "Media quad complex real unsigned with saturation") + +(media-quad-complex-i mqcpxis HI ext argjlo argjhi + (const DI #x7fffffffff) (const DI #xffffff8000000000) + OP_7B OPE1_26 + "Media quad complex imaginary signed with saturation") + +(media-quad-complex-i mqcpxiu UHI zext argjlo argjhi + (const DI #xffffffffff) (const DI 0) + OP_7B OPE1_27 + "Media quad complex imaginary unsigned with saturation") + +(define-pmacro (media-pack src1 src2 targ offset) + (sequence () + (set (halfword hi targ offset) (halfword lo src1 offset)) + (set (halfword lo targ offset) (halfword lo src2 offset))) +) + +(define-pmacro (media-expand-halfword-to-word-semantics cond) + (if cond + (sequence ((UHI tmp)) + (if (and u6 1) + (set tmp (halfword lo FRinti 0)) + (set tmp (halfword hi FRinti 0))) + (set (halfword hi FRintk 0) tmp) + (set (halfword lo FRintk 0) tmp))) +) + +(dni mexpdhw + "Media expand halfword to word" + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + "mexpdhw$pack $FRinti,$u6,$FRintk" + (+ pack FRintk OP_7B FRinti OPE1_32 u6) + (media-expand-halfword-to-word-semantics 1) + ((fr400 (unit u-media-3)) (fr450 (unit u-media-3)) + (fr500 (unit u-media)) (fr550 (unit u-media))) +) + +(dni cmexpdhw + "Conditional media expand halfword to word" + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-1) (FR450-MAJOR M-1) CONDITIONAL) + "cmexpdhw$pack $FRinti,$u6,$FRintk,$CCi,$cond" + (+ pack FRintk OP_76 FRinti CCi cond OPE4_2 u6) + (media-expand-halfword-to-word-semantics (eq CCi (or cond 2))) + ((fr400 (unit u-media-3)) (fr450 (unit u-media-3)) + (fr500 (unit u-media)) (fr550 (unit u-media))) +) + +(define-pmacro (media-expand-halfword-to-double-semantics cond) + (if (register-unaligned FRintkeven 2) + (c-call VOID "@cpu@_media_register_not_aligned") + (if cond + (sequence ((UHI tmp)) + ; a hack to get FRintkeven referenced for profiling + (set FRintkeven (c-raw-call SI "frv_ref_SI" FRintkeven)) + (if (and u6 1) + (set tmp (halfword lo FRinti 0)) + (set tmp (halfword hi FRinti 0))) + (set (halfword hi FRintkeven 0) tmp) + (set (halfword lo FRintkeven 0) tmp) + (set (halfword hi FRintkeven 1) tmp) + (set (halfword lo FRintkeven 1) tmp)))) +) + +(dni mexpdhd + "Media expand halfword to double" + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-2) (FR450-MAJOR M-2)) + "mexpdhd$pack $FRinti,$u6,$FRintkeven" + (+ pack FRintkeven OP_7B FRinti OPE1_33 u6) + (media-expand-halfword-to-double-semantics 1) + ((fr400 (unit u-media-dual-expand + (out FRintk FRintkeven))) + (fr450 (unit u-media-dual-expand + (out FRintk FRintkeven))) + (fr500 (unit u-media-dual-expand + (out FRintk FRintkeven))) + (fr550 (unit u-media-dual-expand))) +) + +(dni cmexpdhd + "Conditional media expand halfword to double" + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-2) (FR450-MAJOR M-2) CONDITIONAL) + "cmexpdhd$pack $FRinti,$u6,$FRintkeven,$CCi,$cond" + (+ pack FRintkeven OP_76 FRinti CCi cond OPE4_3 u6) + (media-expand-halfword-to-double-semantics (eq CCi (or cond 2))) + ((fr400 (unit u-media-dual-expand + (out FRintk FRintkeven))) + (fr450 (unit u-media-dual-expand + (out FRintk FRintkeven))) + (fr500 (unit u-media-dual-expand + (out FRintk FRintkeven))) + (fr550 (unit u-media-dual-expand))) +) + +(dni mpackh + "Media halfword pack" + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + "mpackh$pack $FRinti,$FRintj,$FRintk" + (+ pack FRintk OP_7B FRinti OPE1_34 FRintj) + (media-pack FRinti FRintj FRintk 0) + ((fr400 (unit u-media-3)) (fr450 (unit u-media-3)) + (fr500 (unit u-media)) (fr550 (unit u-media))) +) + +(dni mdpackh + "Media dual pack" + ((UNIT FM01) (FR500-MAJOR M-5) (FR550-MAJOR M-3) + (FR400-MAJOR M-2) (FR450-MAJOR M-2)) + "mdpackh$pack $FRintieven,$FRintjeven,$FRintkeven" + (+ pack FRintkeven OP_7B FRintieven OPE1_36 FRintjeven) + (if (orif (register-unaligned FRintieven 2) + (orif (register-unaligned FRintjeven 2) + (register-unaligned FRintkeven 2))) + (c-call VOID "@cpu@_media_register_not_aligned") + (sequence () + ; hack to get these referenced for profiling + (set FRintieven (c-raw-call SI "frv_ref_SI" FRintieven)) + (set FRintjeven (c-raw-call SI "frv_ref_SI" FRintjeven)) + (set FRintkeven (c-raw-call SI "frv_ref_SI" FRintkeven)) + (media-pack FRintieven FRintjeven FRintkeven 0) + (media-pack FRintieven FRintjeven FRintkeven 1))) + ((fr400 (unit u-media-3-quad + (in FRinti FRintieven) + (in FRintj FRintjeven) + (out FRintk FRintkeven))) + (fr450 (unit u-media-3-quad + (in FRinti FRintieven) + (in FRintj FRintjeven) + (out FRintk FRintkeven))) + (fr500 (unit u-media-quad-arith + (in FRinti FRintieven) + (in FRintj FRintjeven) + (out FRintk FRintkeven))) + (fr550 (unit u-media-quad))) +) + +(define-pmacro (media-unpack src soff targ toff) + (sequence () + (set (halfword hi targ toff) (halfword hi src soff)) + (set (halfword lo targ toff) (halfword hi src soff)) + (set (halfword hi targ (add toff 1)) (halfword lo src soff)) + (set (halfword lo targ (add toff 1)) (halfword lo src soff))) +) + +(dni munpackh + "Media halfword unpack" + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-2) (FR450-MAJOR M-2)) + "munpackh$pack $FRinti,$FRintkeven" + (+ pack FRintkeven OP_7B FRinti OPE1_35 (FRj-null)) + (if (register-unaligned FRintkeven 2) + (c-call VOID "@cpu@_media_register_not_aligned") + (sequence () + ; hack to get these referenced for profiling + (set FRinti (c-raw-call SI "frv_ref_SI" FRinti)) + (set FRintkeven (c-raw-call SI "frv_ref_SI" FRintkeven)) + (media-unpack FRinti 0 FRintkeven 0))) + ((fr400 (unit u-media-dual-expand + (out FRintk FRintkeven))) + (fr450 (unit u-media-dual-expand + (out FRintk FRintkeven))) + (fr500 (unit u-media-dual-expand + (out FRintk FRintkeven))) + (fr550 (unit u-media-dual-expand))) +) + +(dni mdunpackh + "Media dual unpack" + ((UNIT FM01) (FR500-MAJOR M-7) (MACH simple,tomcat,frv)) + "mdunpackh$pack $FRintieven,$FRintk" + (+ pack FRintk OP_7B FRintieven OPE1_37 (FRj-null)) + (if (orif (register-unaligned FRintieven 2) (register-unaligned FRintk 4)) + (c-call VOID "@cpu@_media_register_not_aligned") + (sequence () + ; hack to get these referenced for profiling + (set FRintieven (c-raw-call SI "frv_ref_SI" FRintieven)) + (set FRintk (c-raw-call SI "frv_ref_SI" FRintk)) + (media-unpack FRintieven 0 FRintk 0) + (media-unpack FRintieven 1 FRintk 2))) + ((fr500 (unit u-media-dual-unpack + (in FRinti FRintieven)))) +) + +(define-pmacro (ubyte num arg offset) + (reg (.sym h-fr_ num) (add (index-of arg) offset))) + +(define-pmacro (mbtoh-semantics cond) + (if (register-unaligned FRintkeven 2) + (c-call VOID "@cpu@_media_register_not_aligned") + (if cond + (sequence () + (set (halfword hi FRintkeven 0) (ubyte 3 FRintj 0)) + (set (halfword lo FRintkeven 0) (ubyte 2 FRintj 0)) + (set (halfword hi FRintkeven 1) (ubyte 1 FRintj 0)) + (set (halfword lo FRintkeven 1) (ubyte 0 FRintj 0))))) +) + +(dni mbtoh + "Media convert byte to halfword" + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-2) (FR450-MAJOR M-2)) + "mbtoh$pack $FRintj,$FRintkeven" + (+ pack FRintkeven OP_7B (FRi-null) OPE1_38 FRintj) + (sequence () + ; hack to get these referenced for profiling + (set FRintj (c-raw-call SI "frv_ref_SI" FRintj)) + (set FRintkeven (c-raw-call SI "frv_ref_SI" FRintkeven)) + (mbtoh-semantics 1)) + ((fr400 (unit u-media-dual-expand + (out FRintk FRintkeven))) + (fr450 (unit u-media-dual-expand + (out FRintk FRintkeven))) + (fr500 (unit u-media-dual-btoh + (out FRintk FRintkeven))) + (fr550 (unit u-media-dual-expand))) +) + +(dni cmbtoh + "Conditional media convert byte to halfword" + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-2) (FR450-MAJOR M-2) CONDITIONAL) + "cmbtoh$pack $FRintj,$FRintkeven,$CCi,$cond" + (+ pack FRintkeven OP_77 (FRi-null) CCi cond OPE4_0 FRintj) + (sequence () + ; hack to get these referenced for profiling + (set FRintj (c-raw-call SI "frv_ref_SI" FRintj)) + (set FRintkeven (c-raw-call SI "frv_ref_SI" FRintkeven)) + (mbtoh-semantics (eq CCi (or cond 2)))) + ((fr400 (unit u-media-dual-expand + (out FRintk FRintkeven))) + (fr450 (unit u-media-dual-expand + (out FRintk FRintkeven))) + (fr500 (unit u-media-dual-btoh + (out FRintk FRintkeven))) + (fr550 (unit u-media-dual-expand + (in FRinti FRintj)))) +) + +(define-pmacro (mhtob-semantics cond) + (if (register-unaligned FRintjeven 2) + (c-call VOID "@cpu@_media_register_not_aligned") + (if cond + (sequence () + (set (ubyte 3 FRintk 0) (halfword hi FRintjeven 0)) + (set (ubyte 2 FRintk 0) (halfword lo FRintjeven 0)) + (set (ubyte 1 FRintk 0) (halfword hi FRintjeven 1)) + (set (ubyte 0 FRintk 0) (halfword lo FRintjeven 1))))) +) + +(dni mhtob + "Media convert halfword to byte" + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-2) (FR450-MAJOR M-2)) + "mhtob$pack $FRintjeven,$FRintk" + (+ pack FRintk OP_7B (FRi-null) OPE1_39 FRintjeven) + (sequence () + ; hack to get these referenced for profiling + (set FRintjeven (c-raw-call SI "frv_ref_SI" FRintjeven)) + (set FRintk (c-raw-call SI "frv_ref_SI" FRintk)) + (mhtob-semantics 1)) + ((fr400 (unit u-media-dual-htob + (in FRintj FRintjeven))) + (fr450 (unit u-media-dual-htob + (in FRintj FRintjeven))) + (fr500 (unit u-media-dual-htob + (in FRintj FRintjeven))) + (fr550 (unit u-media-3-dual + (in FRinti FRintjeven)))) +) + +(dni cmhtob + "Conditional media convert halfword to byte" + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-2) (FR450-MAJOR M-2) CONDITIONAL) + "cmhtob$pack $FRintjeven,$FRintk,$CCi,$cond" + (+ pack FRintk OP_77 (FRi-null) CCi cond OPE4_1 FRintjeven) + (sequence () + ; hack to get these referenced for profiling + (set FRintjeven (c-raw-call SI "frv_ref_SI" FRintjeven)) + (set FRintk (c-raw-call SI "frv_ref_SI" FRintk)) + (mhtob-semantics (eq CCi (or cond 2)))) + ((fr400 (unit u-media-dual-htob + (in FRintj FRintjeven))) + (fr450 (unit u-media-dual-htob + (in FRintj FRintjeven))) + (fr500 (unit u-media-dual-htob + (in FRintj FRintjeven))) + (fr550 (unit u-media-3-dual + (in FRinti FRintjeven)))) +) + +(define-pmacro (mbtohe-semantics cond) + (if (register-unaligned FRintk 4) + (c-call VOID "@cpu@_media_register_not_aligned") + (if cond + (sequence () + (set (halfword hi FRintk 0) (ubyte 3 FRintj 0)) + (set (halfword lo FRintk 0) (ubyte 3 FRintj 0)) + (set (halfword hi FRintk 1) (ubyte 2 FRintj 0)) + (set (halfword lo FRintk 1) (ubyte 2 FRintj 0)) + (set (halfword hi FRintk 2) (ubyte 1 FRintj 0)) + (set (halfword lo FRintk 2) (ubyte 1 FRintj 0)) + (set (halfword hi FRintk 3) (ubyte 0 FRintj 0)) + (set (halfword lo FRintk 3) (ubyte 0 FRintj 0))))) +) + +(dni mbtohe + "Media convert byte to halfword extended" + ((UNIT FM01) (FR500-MAJOR M-7) (MACH simple,tomcat,frv)) + "mbtohe$pack $FRintj,$FRintk" + (+ pack FRintk OP_7B (FRi-null) OPE1_3A FRintj) + (sequence () + ; hack to get these referenced for profiling + (set FRintj (c-raw-call SI "frv_ref_SI" FRintj)) + (set FRintk (c-raw-call SI "frv_ref_SI" FRintk)) + (mbtohe-semantics 1)) + ((fr500 (unit u-media-dual-btohe))) +) + +(dni cmbtohe + "Conditional media convert byte to halfword extended" + ((UNIT FM01) (FR500-MAJOR M-7) CONDITIONAL (MACH simple,tomcat,frv)) + "cmbtohe$pack $FRintj,$FRintk,$CCi,$cond" + (+ pack FRintk OP_77 (FRi-null) CCi cond OPE4_2 FRintj) + (sequence () + ; hack to get these referenced for profiling + (set FRintj (c-raw-call SI "frv_ref_SI" FRintj)) + (set FRintk (c-raw-call SI "frv_ref_SI" FRintk)) + (mbtohe-semantics (eq CCi (or cond 2)))) + ((fr500 (unit u-media-dual-btohe))) +) + +; Media NOP +; A special case of mclracc +(dni mnop "Media nop" + ((UNIT FMALL) (FR500-MAJOR M-1) (FR550-MAJOR M-1) + (FR400-MAJOR M-1) (FR450-MAJOR M-1)) + "mnop$pack" + (+ pack (f-ACC40Sk 63) OP_7B (f-A 1) (misc-null-10) OPE1_3B (FRj-null)) + (nop) + () +) + +; mclracc with #A==0 +(dni mclracc-0 + "Media clear accumulator(s)" + ((UNIT FM01) (FR500-MAJOR M-3) (FR550-MAJOR M-3) + (FR400-MAJOR M-1) (FR450-MAJOR M-3)) + "mclracc$pack $ACC40Sk,$A0" + (+ pack ACC40Sk OP_7B (f-A 0) (misc-null-10) OPE1_3B (FRj-null)) + (c-call VOID "@cpu@_clear_accumulators" (index-of ACC40Sk) 0) + ((fr400 (unit u-media-4)) (fr450 (unit u-media-4)) + (fr500 (unit u-media)) (fr550 (unit u-media-3-mclracc))) +) + +; mclracc with #A==1 +(dni mclracc-1 + "Media clear accumulator(s)" + ((UNIT MCLRACC-1) (FR500-MAJOR M-6) (FR550-MAJOR M-3) + (FR400-MAJOR M-2) (FR450-MAJOR M-4)) + "mclracc$pack $ACC40Sk,$A1" + (+ pack ACC40Sk OP_7B (f-A 1) (misc-null-10) OPE1_3B (FRj-null)) + (c-call VOID "@cpu@_clear_accumulators" (index-of ACC40Sk) 1) + ((fr400 (unit u-media-4)) (fr450 (unit u-media-4-mclracca)) + (fr500 (unit u-media)) (fr550 (unit u-media-3-mclracc))) +) + +(dni mrdacc + "Media read accumulator" + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-1) (FR450-MAJOR M-5)) + "mrdacc$pack $ACC40Si,$FRintk" + (+ pack FRintk OP_7B ACC40Si OPE1_3C (FRj-null)) + (set FRintk ACC40Si) + ((fr400 (unit u-media-4)) (fr450 (unit u-media-4)) + (fr500 (unit u-media)) (fr550 (unit u-media-3-acc))) +) + +(dni mrdaccg + "Media read accumulator guard" + ((UNIT FM01) (FR500-MAJOR M-2) (FR550-MAJOR M-3) + (FR400-MAJOR M-1) (FR450-MAJOR M-5)) + "mrdaccg$pack $ACCGi,$FRintk" + (+ pack FRintk OP_7B ACCGi OPE1_3E (FRj-null)) + (set FRintk ACCGi) + ((fr400 (unit u-media-4-accg)) (fr450 (unit u-media-4-accg)) + (fr500 (unit u-media)) (fr550 (unit u-media-3-acc (in ACC40Si ACCGi)))) +) + +(dni mwtacc + "Media write accumulator" + ((UNIT FM01) (FR500-MAJOR M-3) (FR550-MAJOR M-3) + (FR400-MAJOR M-1) (FR450-MAJOR M-3)) + "mwtacc$pack $FRinti,$ACC40Sk" + (+ pack ACC40Sk OP_7B FRinti OPE1_3D (FRj-null)) + (set ACC40Sk (or (and ACC40Sk (const DI #xffffffff00000000)) + FRinti)) + ((fr400 (unit u-media-4)) (fr450 (unit u-media-4)) + (fr500 (unit u-media)) (fr550 (unit u-media-3-wtacc))) +) + +(dni mwtaccg + "Media write accumulator guard" + ((UNIT FM01) (FR500-MAJOR M-3) (FR550-MAJOR M-3) + (FR400-MAJOR M-1) (FR450-MAJOR M-3)) + "mwtaccg$pack $FRinti,$ACCGk" + (+ pack ACCGk OP_7B FRinti OPE1_3F (FRj-null)) + (sequence () + ; hack to get these referenced for profiling + (c-raw-call VOID "frv_ref_SI" ACCGk) + (set ACCGk FRinti)) + ((fr400 (unit u-media-4-accg)) (fr450 (unit u-media-4-accg)) + (fr500 (unit u-media)) (fr550 (unit u-media-3-wtacc (in ACC40Sk ACCGk)))) +) + +(define-pmacro (media-cop num op) + (dni (.sym mcop num) + "Media custom instruction" + ((UNIT FM01) (FR500-MAJOR M-1) (MACH frv)) + (.str "mcop" num "$pack $FRi,$FRj,$FRk") + (+ pack FRk op FRi OPE1_00 FRj) + (c-call VOID "@cpu@_media_cop" num) + () + ) +) + +(media-cop 1 OP_7C) +(media-cop 2 OP_7D) + +; nop +; A nop is defined to be a "ori gr0,0,gr0" +; This needn't be a macro-insn, but making it one greatly simplifies decode.c +; On the other hand spending a little time in the decoder is often worth it. +; +(dnmi nop "nop" + ((UNIT IALL) (FR500-MAJOR I-1) (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + "nop$pack" + (emit ori pack (GRi 0) (s12 0) (GRk 0)) +) + +; Floating point NOP +(dni fnop + "Floating point nop" + ((UNIT FMALL) (FR500-MAJOR F-8) (FR550-MAJOR F-1) (MACH simple,tomcat,fr500,fr550,frv)) + "fnop$pack" + (+ pack (rd-null) OP_79 (FRi-null) OPE1_0D (FRj-null)) + (nop) + () +) + +; A return instruction +(dnmi ret "return" + (NO-DIS (UNIT B01) (FR500-MAJOR B-3) + (FR400-MAJOR B-3) (FR450-MAJOR B-3)) + "ret$pack" + (emit bralr pack (hint_taken 2)) +) + +(dnmi cmp "compare" + (NO-DIS (UNIT IALL) (FR500-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + "cmp$pack $GRi,$GRj,$ICCi_1" + (emit subcc pack GRi GRj (GRk 0) ICCi_1) +) + +(dnmi cmpi "compare immediate" + (NO-DIS (UNIT IALL) (FR500-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + "cmpi$pack $GRi,$s10,$ICCi_1" + (emit subicc pack GRi s10 (GRk 0) ICCi_1) +) + +(dnmi ccmp "conditional compare" + (NO-DIS (UNIT IALL) (FR500-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) CONDITIONAL) + "ccmp$pack $GRi,$GRj,$CCi,$cond" + (emit csubcc pack GRi GRj (GRk 0) CCi cond) +) + +(dnmi mov "move" + (NO-DIS (UNIT IALL) (FR500-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1)) + "mov$pack $GRi,$GRk" + (emit ori pack GRi (s12 0) GRk) +) + +(dnmi cmov "conditional move" + (NO-DIS (UNIT IALL) (FR500-MAJOR I-1) + (FR400-MAJOR I-1) (FR450-MAJOR I-1) CONDITIONAL) + "cmov$pack $GRi,$GRk,$CCi,$cond" + (emit cor pack GRi (GRj 0) GRk CCi cond) +) diff --git a/cpu/frv.opc b/cpu/frv.opc new file mode 100644 index 00000000000..0b9c93c8dc4 --- /dev/null +++ b/cpu/frv.opc @@ -0,0 +1,1918 @@ +/* Fujitsu FRV opcode support, for GNU Binutils. -*- C -*- + + Copyright 2000, 2001, 2003, 2004, 2005, 2007, 2009 + Free Software Foundation, Inc. + + Contributed by Red Hat Inc; developed under contract from Fujitsu. + + 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. */ + + +/* This file is an addendum to frv.cpu. Heavy use of C code isn't + appropriate in .cpu files, so it resides here. This especially applies + to assembly/disassembly where parsing/printing can be quite involved. + Such things aren't really part of the specification of the cpu, per se, + so .cpu files provide the general framework and .opc files handle the + nitty-gritty details as necessary. + + Each section is delimited with start and end markers. + + <arch>-opc.h additions use: "-- opc.h" + <arch>-opc.c additions use: "-- opc.c" + <arch>-asm.c additions use: "-- asm.c" + <arch>-dis.c additions use: "-- dis.c" + <arch>-ibd.h additions use: "-- ibd.h". */ + +/* -- opc.h */ + +#undef CGEN_DIS_HASH_SIZE +#define CGEN_DIS_HASH_SIZE 128 +#undef CGEN_DIS_HASH +#define CGEN_DIS_HASH(buffer, value) (((value) >> 18) & 127) + +/* Allows reason codes to be output when assembler errors occur. */ +#define CGEN_VERBOSE_ASSEMBLER_ERRORS + +/* Vliw support. */ +#define FRV_VLIW_SIZE 8 /* fr550 has largest vliw size of 8. */ +#define PAD_VLIW_COMBO ,UNIT_NIL,UNIT_NIL,UNIT_NIL,UNIT_NIL + +typedef CGEN_ATTR_VALUE_ENUM_TYPE VLIW_COMBO[FRV_VLIW_SIZE]; + +typedef struct +{ + int next_slot; + int constraint_violation; + unsigned long mach; + unsigned long elf_flags; + CGEN_ATTR_VALUE_ENUM_TYPE * unit_mapping; + VLIW_COMBO * current_vliw; + CGEN_ATTR_VALUE_ENUM_TYPE major[FRV_VLIW_SIZE]; + const CGEN_INSN * insn[FRV_VLIW_SIZE]; +} FRV_VLIW; + +int frv_is_branch_major (CGEN_ATTR_VALUE_ENUM_TYPE, unsigned long); +int frv_is_float_major (CGEN_ATTR_VALUE_ENUM_TYPE, unsigned long); +int frv_is_media_major (CGEN_ATTR_VALUE_ENUM_TYPE, unsigned long); +int frv_is_branch_insn (const CGEN_INSN *); +int frv_is_float_insn (const CGEN_INSN *); +int frv_is_media_insn (const CGEN_INSN *); +void frv_vliw_reset (FRV_VLIW *, unsigned long, unsigned long); +int frv_vliw_add_insn (FRV_VLIW *, const CGEN_INSN *); +int spr_valid (long); +/* -- */ + +/* -- opc.c */ +#include "elf/frv.h" +#include <stdio.h> + +/* Returns TRUE if {MAJOR,MACH} is a major branch of the FRV + development tree. */ + +bfd_boolean +frv_is_branch_major (CGEN_ATTR_VALUE_ENUM_TYPE major, unsigned long mach) +{ + switch (mach) + { + case bfd_mach_fr400: + if (major >= FR400_MAJOR_B_1 && major <= FR400_MAJOR_B_6) + return TRUE; + break; + case bfd_mach_fr450: + if (major >= FR450_MAJOR_B_1 && major <= FR450_MAJOR_B_6) + return TRUE; + break; + default: + if (major >= FR500_MAJOR_B_1 && major <= FR500_MAJOR_B_6) + return TRUE; + break; + } + + return FALSE; +} + +/* Returns TRUE if {MAJOR,MACH} supports floating point insns. */ + +bfd_boolean +frv_is_float_major (CGEN_ATTR_VALUE_ENUM_TYPE major, unsigned long mach) +{ + switch (mach) + { + case bfd_mach_fr400: + case bfd_mach_fr450: + return FALSE; + default: + if (major >= FR500_MAJOR_F_1 && major <= FR500_MAJOR_F_8) + return TRUE; + break; + } + + return FALSE; +} + +/* Returns TRUE if {MAJOR,MACH} supports media insns. */ + +bfd_boolean +frv_is_media_major (CGEN_ATTR_VALUE_ENUM_TYPE major, unsigned long mach) +{ + switch (mach) + { + case bfd_mach_fr400: + if (major >= FR400_MAJOR_M_1 && major <= FR400_MAJOR_M_2) + return TRUE; + break; + case bfd_mach_fr450: + if (major >= FR450_MAJOR_M_1 && major <= FR450_MAJOR_M_6) + return TRUE; + break; + default: + if (major >= FR500_MAJOR_M_1 && major <= FR500_MAJOR_M_8) + return TRUE; + break; + } + + return FALSE; +} + +bfd_boolean +frv_is_branch_insn (const CGEN_INSN *insn) +{ + if (frv_is_branch_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR), + bfd_mach_fr400)) + return TRUE; + if (frv_is_branch_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR450_MAJOR), + bfd_mach_fr450)) + return TRUE; + if (frv_is_branch_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR), + bfd_mach_fr500)) + return TRUE; + + return FALSE; +} + +bfd_boolean +frv_is_float_insn (const CGEN_INSN *insn) +{ + if (frv_is_float_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR), + bfd_mach_fr400)) + return TRUE; + if (frv_is_float_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR450_MAJOR), + bfd_mach_fr450)) + return TRUE; + if (frv_is_float_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR), + bfd_mach_fr500)) + return TRUE; + + return FALSE; +} + +bfd_boolean +frv_is_media_insn (const CGEN_INSN *insn) +{ + if (frv_is_media_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR), + bfd_mach_fr400)) + return TRUE; + if (frv_is_media_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR450_MAJOR), + bfd_mach_fr450)) + return TRUE; + if (frv_is_media_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR), + bfd_mach_fr500)) + return TRUE; + + return FALSE; +} + +/* This table represents the allowable packing for vliw insns for the fr400. + The fr400 has only 2 vliw slots. Represent this by not allowing any insns + in the extra slots. + Subsets of any given row are also allowed. */ +static VLIW_COMBO fr400_allowed_vliw[] = +{ + /* slot0 slot1 slot2 slot3 */ + { UNIT_I0, UNIT_I1, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO }, + { UNIT_I0, UNIT_FM0, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO }, + { UNIT_I0, UNIT_B0, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO }, + { UNIT_FM0, UNIT_FM1, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO }, + { UNIT_FM0, UNIT_B0, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO }, + { UNIT_B0, UNIT_NIL, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO }, + { UNIT_C, UNIT_NIL, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO }, + { UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO } +}; + +/* This table represents the allowable packing for vliw insns for the fr500. + The fr500 has only 4 vliw slots. Represent this by not allowing any insns + in the extra slots. + Subsets of any given row are also allowed. */ +static VLIW_COMBO fr500_allowed_vliw[] = +{ + /* slot0 slot1 slot2 slot3 */ + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1 PAD_VLIW_COMBO }, + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_B0 PAD_VLIW_COMBO }, + { UNIT_I0, UNIT_FM0, UNIT_FM1, UNIT_B0 PAD_VLIW_COMBO }, + { UNIT_I0, UNIT_FM0, UNIT_B0, UNIT_B1 PAD_VLIW_COMBO }, + { UNIT_I0, UNIT_I1, UNIT_B0, UNIT_B1 PAD_VLIW_COMBO }, + { UNIT_I0, UNIT_B0, UNIT_B1, UNIT_NIL PAD_VLIW_COMBO }, + { UNIT_FM0, UNIT_FM1, UNIT_B0, UNIT_B1 PAD_VLIW_COMBO }, + { UNIT_FM0, UNIT_B0, UNIT_B1, UNIT_NIL PAD_VLIW_COMBO }, + { UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO }, + { UNIT_C, UNIT_NIL, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO }, + { UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL PAD_VLIW_COMBO } +}; + +/* This table represents the allowable packing for vliw insns for the fr550. + Subsets of any given row are also allowed. */ +static VLIW_COMBO fr550_allowed_vliw[] = +{ + /* slot0 slot1 slot2 slot3 slot4 slot5 slot6 slot7 */ + { UNIT_I0, UNIT_I1, UNIT_I2, UNIT_I3, UNIT_B0, UNIT_B1 , UNIT_NIL, UNIT_NIL }, + { UNIT_I0, UNIT_I1, UNIT_I2, UNIT_B0, UNIT_B1 , UNIT_NIL, UNIT_NIL, UNIT_NIL }, + { UNIT_I0, UNIT_I1, UNIT_B0, UNIT_B1 , UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL }, + { UNIT_I0, UNIT_B0, UNIT_B1 , UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL }, + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_FM2, UNIT_I3, UNIT_FM3 }, + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_FM2, UNIT_I3, UNIT_B0 }, + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_FM2, UNIT_FM3, UNIT_B0 }, + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_FM2, UNIT_B0, UNIT_B1 }, + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_I3, UNIT_B0, UNIT_B1 }, + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_I2, UNIT_B0, UNIT_B1, UNIT_NIL }, + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_FM2, UNIT_FM3, UNIT_B0, UNIT_B1 }, + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_FM2, UNIT_FM3, UNIT_B0, UNIT_B1 }, + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_FM2, UNIT_B0, UNIT_B1, UNIT_NIL }, + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL }, + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_I2, UNIT_I3, UNIT_B0, UNIT_B1, UNIT_NIL }, + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_I2, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL }, + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL }, + { UNIT_I0, UNIT_FM0, UNIT_FM1, UNIT_FM2, UNIT_FM3, UNIT_B0, UNIT_B1, UNIT_NIL }, + { UNIT_I0, UNIT_FM0, UNIT_FM1, UNIT_FM2, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL }, + { UNIT_I0, UNIT_FM0, UNIT_FM1, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL }, + { UNIT_I0, UNIT_FM0, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL }, + { UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL }, + { UNIT_C, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL }, + { UNIT_FM0, UNIT_FM1, UNIT_FM2, UNIT_FM3, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL }, + { UNIT_FM0, UNIT_FM1, UNIT_FM2, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL }, + { UNIT_FM0, UNIT_FM1, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL }, + { UNIT_FM0, UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL }, + { UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL } +}; + +/* Some insns are assigned specialized implementation units which map to + different actual implementation units on different machines. These + tables perform that mapping. */ +static CGEN_ATTR_VALUE_ENUM_TYPE fr400_unit_mapping[] = +{ +/* unit in insn actual unit */ +/* NIL */ UNIT_NIL, +/* I0 */ UNIT_I0, +/* I1 */ UNIT_I1, +/* I01 */ UNIT_I01, +/* I2 */ UNIT_NIL, /* no I2 or I3 unit */ +/* I3 */ UNIT_NIL, +/* IALL */ UNIT_I01, /* only I0 and I1 units */ +/* FM0 */ UNIT_FM0, +/* FM1 */ UNIT_FM1, +/* FM01 */ UNIT_FM01, +/* FM2 */ UNIT_NIL, /* no F2 or M2 units */ +/* FM3 */ UNIT_NIL, /* no F3 or M3 units */ +/* FMALL */ UNIT_FM01,/* Only F0,F1,M0,M1 units */ +/* FMLOW */ UNIT_FM0, /* Only F0,M0 units */ +/* B0 */ UNIT_B0, /* branches only in B0 unit. */ +/* B1 */ UNIT_B0, +/* B01 */ UNIT_B0, +/* C */ UNIT_C, +/* MULT-DIV */ UNIT_I0, /* multiply and divide only in I0 unit. */ +/* IACC */ UNIT_I01, /* iacc multiply in I0 or I1 unit. */ +/* LOAD */ UNIT_I0, /* load only in I0 unit. */ +/* STORE */ UNIT_I0, /* store only in I0 unit. */ +/* SCAN */ UNIT_I0, /* scan only in I0 unit. */ +/* DCPL */ UNIT_C, /* dcpl only in C unit. */ +/* MDUALACC */ UNIT_FM0, /* media dual acc insn only in FM0 unit. */ +/* MDCUTSSI */ UNIT_FM0, /* mdcutssi only in FM0 unit. */ +/* MCLRACC-1*/ UNIT_FM0 /* mclracc,A==1 insn only in FM0 unit. */ +}; + +/* Some insns are assigned specialized implementation units which map to + different actual implementation units on different machines. These + tables perform that mapping. */ +static CGEN_ATTR_VALUE_ENUM_TYPE fr450_unit_mapping[] = +{ +/* unit in insn actual unit */ +/* NIL */ UNIT_NIL, +/* I0 */ UNIT_I0, +/* I1 */ UNIT_I1, +/* I01 */ UNIT_I01, +/* I2 */ UNIT_NIL, /* no I2 or I3 unit */ +/* I3 */ UNIT_NIL, +/* IALL */ UNIT_I01, /* only I0 and I1 units */ +/* FM0 */ UNIT_FM0, +/* FM1 */ UNIT_FM1, +/* FM01 */ UNIT_FM01, +/* FM2 */ UNIT_NIL, /* no F2 or M2 units */ +/* FM3 */ UNIT_NIL, /* no F3 or M3 units */ +/* FMALL */ UNIT_FM01,/* Only F0,F1,M0,M1 units */ +/* FMLOW */ UNIT_FM0, /* Only F0,M0 units */ +/* B0 */ UNIT_B0, /* branches only in B0 unit. */ +/* B1 */ UNIT_B0, +/* B01 */ UNIT_B0, +/* C */ UNIT_C, +/* MULT-DIV */ UNIT_I0, /* multiply and divide only in I0 unit. */ +/* IACC */ UNIT_I01, /* iacc multiply in I0 or I1 unit. */ +/* LOAD */ UNIT_I0, /* load only in I0 unit. */ +/* STORE */ UNIT_I0, /* store only in I0 unit. */ +/* SCAN */ UNIT_I0, /* scan only in I0 unit. */ +/* DCPL */ UNIT_I0, /* dcpl only in I0 unit. */ +/* MDUALACC */ UNIT_FM0, /* media dual acc insn only in FM0 unit. */ +/* MDCUTSSI */ UNIT_FM01, /* mdcutssi in FM0 or FM1. */ +/* MCLRACC-1*/ UNIT_FM0 /* mclracc,A==1 insn only in FM0 unit. */ +}; + +static CGEN_ATTR_VALUE_ENUM_TYPE fr500_unit_mapping[] = +{ +/* unit in insn actual unit */ +/* NIL */ UNIT_NIL, +/* I0 */ UNIT_I0, +/* I1 */ UNIT_I1, +/* I01 */ UNIT_I01, +/* I2 */ UNIT_NIL, /* no I2 or I3 unit */ +/* I3 */ UNIT_NIL, +/* IALL */ UNIT_I01, /* only I0 and I1 units */ +/* FM0 */ UNIT_FM0, +/* FM1 */ UNIT_FM1, +/* FM01 */ UNIT_FM01, +/* FM2 */ UNIT_NIL, /* no F2 or M2 units */ +/* FM3 */ UNIT_NIL, /* no F3 or M2 units */ +/* FMALL */ UNIT_FM01,/* Only F0,F1,M0,M1 units */ +/* FMLOW */ UNIT_FM0, /* Only F0,M0 units */ +/* B0 */ UNIT_B0, +/* B1 */ UNIT_B1, +/* B01 */ UNIT_B01, +/* C */ UNIT_C, +/* MULT-DIV */ UNIT_I01, /* multiply and divide in I0 or I1 unit. */ +/* IACC */ UNIT_NIL, /* iacc multiply not implemented */ +/* LOAD */ UNIT_I01, /* load in I0 or I1 unit. */ +/* STORE */ UNIT_I0, /* store only in I0 unit. */ +/* SCAN */ UNIT_I01, /* scan in I0 or I1 unit. */ +/* DCPL */ UNIT_C, /* dcpl only in C unit. */ +/* MDUALACC */ UNIT_FM0, /* media dual acc insn only in FM0 unit. */ +/* MDCUTSSI */ UNIT_FM0, /* mdcutssi only in FM0 unit. */ +/* MCLRACC-1*/ UNIT_FM01 /* mclracc,A==1 in FM0 or FM1 unit. */ +}; + +static CGEN_ATTR_VALUE_ENUM_TYPE fr550_unit_mapping[] = +{ +/* unit in insn actual unit */ +/* NIL */ UNIT_NIL, +/* I0 */ UNIT_I0, +/* I1 */ UNIT_I1, +/* I01 */ UNIT_I01, +/* I2 */ UNIT_I2, +/* I3 */ UNIT_I3, +/* IALL */ UNIT_IALL, +/* FM0 */ UNIT_FM0, +/* FM1 */ UNIT_FM1, +/* FM01 */ UNIT_FM01, +/* FM2 */ UNIT_FM2, +/* FM3 */ UNIT_FM3, +/* FMALL */ UNIT_FMALL, +/* FMLOW */ UNIT_FM01, /* Only F0,F1,M0,M1 units */ +/* B0 */ UNIT_B0, +/* B1 */ UNIT_B1, +/* B01 */ UNIT_B01, +/* C */ UNIT_C, +/* MULT-DIV */ UNIT_I01, /* multiply and divide in I0 or I1 unit. */ +/* IACC */ UNIT_NIL, /* iacc multiply not implemented. */ +/* LOAD */ UNIT_I01, /* load in I0 or I1 unit. */ +/* STORE */ UNIT_I01, /* store in I0 or I1 unit. */ +/* SCAN */ UNIT_IALL, /* scan in any integer unit. */ +/* DCPL */ UNIT_I0, /* dcpl only in I0 unit. */ +/* MDUALACC */ UNIT_FMALL,/* media dual acc insn in all media units */ +/* MDCUTSSI */ UNIT_FM01, /* mdcutssi in FM0 or FM1 unit. */ +/* MCLRACC-1*/ UNIT_FM01 /* mclracc,A==1 in FM0 or FM1 unit. */ +}; + +void +frv_vliw_reset (FRV_VLIW *vliw, unsigned long mach, unsigned long elf_flags) +{ + vliw->next_slot = 0; + vliw->constraint_violation = 0; + vliw->mach = mach; + vliw->elf_flags = elf_flags; + + switch (mach) + { + case bfd_mach_fr400: + vliw->current_vliw = fr400_allowed_vliw; + vliw->unit_mapping = fr400_unit_mapping; + break; + case bfd_mach_fr450: + vliw->current_vliw = fr400_allowed_vliw; + vliw->unit_mapping = fr450_unit_mapping; + break; + case bfd_mach_fr550: + vliw->current_vliw = fr550_allowed_vliw; + vliw->unit_mapping = fr550_unit_mapping; + break; + default: + vliw->current_vliw = fr500_allowed_vliw; + vliw->unit_mapping = fr500_unit_mapping; + break; + } +} + +/* Return TRUE if unit1 is a match for unit2. + Unit1 comes from the insn's UNIT attribute. unit2 comes from one of the + *_allowed_vliw tables above. */ +static bfd_boolean +match_unit (FRV_VLIW *vliw, + CGEN_ATTR_VALUE_ENUM_TYPE unit1, CGEN_ATTR_VALUE_ENUM_TYPE unit2) +{ + /* Map any specialized implementation units to actual ones. */ + unit1 = vliw->unit_mapping[unit1]; + + if (unit1 == unit2) + return TRUE; + if (unit1 < unit2) + return FALSE; + + switch (unit1) + { + case UNIT_I01: + case UNIT_FM01: + case UNIT_B01: + /* The 01 versions of these units are within 2 enums of the 0 or 1 + versions. */ + if (unit1 - unit2 <= 2) + return TRUE; + break; + case UNIT_IALL: + case UNIT_FMALL: + /* The ALL versions of these units are within 5 enums of the 0, 1, 2 or 3 + versions. */ + if (unit1 - unit2 <= 5) + return TRUE; + break; + default: + break; + } + + return FALSE; +} + +/* Return TRUE if the vliws match, FALSE otherwise. */ + +static bfd_boolean +match_vliw (VLIW_COMBO *vliw1, VLIW_COMBO *vliw2, int vliw_size) +{ + int i; + + for (i = 0; i < vliw_size; ++i) + if ((*vliw1)[i] != (*vliw2)[i]) + return FALSE; + + return TRUE; +} + +/* Find the next vliw vliw in the table that can accomodate the new insn. + If one is found then return it. Otherwise return NULL. */ + +static VLIW_COMBO * +add_next_to_vliw (FRV_VLIW *vliw, CGEN_ATTR_VALUE_ENUM_TYPE unit) +{ + int next = vliw->next_slot; + VLIW_COMBO *current = vliw->current_vliw; + VLIW_COMBO *potential; + + if (next <= 0) + { + fprintf (stderr, "frv-opc.c line %d: bad vliw->next_slot value.\n", + __LINE__); + abort (); /* Should never happen. */ + } + + /* The table is sorted by units allowed within slots, so vliws with + identical starting sequences are together. */ + potential = current; + do + { + if (match_unit (vliw, unit, (*potential)[next])) + return potential; + ++potential; + } + while (match_vliw (potential, current, next)); + + return NULL; +} + +/* Look for the given major insn type in the given vliw. + Returns TRUE if found, FALSE otherwise. */ + +static bfd_boolean +find_major_in_vliw (FRV_VLIW *vliw, CGEN_ATTR_VALUE_ENUM_TYPE major) +{ + int i; + + for (i = 0; i < vliw->next_slot; ++i) + if (vliw->major[i] == major) + return TRUE; + + return FALSE; +} + +/* Check for constraints between the insns in the vliw due to major insn + types. */ + +static bfd_boolean +fr400_check_insn_major_constraints (FRV_VLIW *vliw, CGEN_ATTR_VALUE_ENUM_TYPE major) +{ + /* In the cpu file, all media insns are represented as being allowed in + both media units. This makes it easier since this is the case for fr500. + Catch the invalid combinations here. Insns of major class FR400_MAJOR_M_2 + cannot coexist with any other media insn in a vliw. */ + switch (major) + { + case FR400_MAJOR_M_2: + return ! find_major_in_vliw (vliw, FR400_MAJOR_M_1) + && ! find_major_in_vliw (vliw, FR400_MAJOR_M_2); + case FR400_MAJOR_M_1: + return ! find_major_in_vliw (vliw, FR400_MAJOR_M_2); + default: + break; + } + return TRUE; +} + +static bfd_boolean +fr450_check_insn_major_constraints (FRV_VLIW *vliw, CGEN_ATTR_VALUE_ENUM_TYPE major) +{ + CGEN_ATTR_VALUE_ENUM_TYPE other_major; + + /* Our caller guarantees there's at least one other instruction. */ + other_major = CGEN_INSN_ATTR_VALUE (vliw->insn[0], CGEN_INSN_FR450_MAJOR); + + /* (M4, M5) and (M4, M6) are allowed. */ + if (other_major == FR450_MAJOR_M_4) + if (major == FR450_MAJOR_M_5 || major == FR450_MAJOR_M_6) + return TRUE; + + /* Otherwise, instructions in even-numbered media categories cannot be + executed in parallel with other media instructions. */ + switch (major) + { + case FR450_MAJOR_M_2: + case FR450_MAJOR_M_4: + case FR450_MAJOR_M_6: + return !(other_major >= FR450_MAJOR_M_1 + && other_major <= FR450_MAJOR_M_6); + + case FR450_MAJOR_M_1: + case FR450_MAJOR_M_3: + case FR450_MAJOR_M_5: + return !(other_major == FR450_MAJOR_M_2 + || other_major == FR450_MAJOR_M_4 + || other_major == FR450_MAJOR_M_6); + + default: + return TRUE; + } +} + +static bfd_boolean +find_unit_in_vliw (FRV_VLIW *vliw, CGEN_ATTR_VALUE_ENUM_TYPE unit) +{ + int i; + + for (i = 0; i < vliw->next_slot; ++i) + if (CGEN_INSN_ATTR_VALUE (vliw->insn[i], CGEN_INSN_UNIT) == unit) + return TRUE; + + return FALSE; /* Not found. */ +} + +static bfd_boolean +find_major_in_slot (FRV_VLIW *vliw, + CGEN_ATTR_VALUE_ENUM_TYPE major, + CGEN_ATTR_VALUE_ENUM_TYPE slot) +{ + int i; + + for (i = 0; i < vliw->next_slot; ++i) + if (vliw->major[i] == major && (*vliw->current_vliw)[i] == slot) + return TRUE; + + return FALSE; +} + +static bfd_boolean +fr550_find_media_in_vliw (FRV_VLIW *vliw) +{ + int i; + + for (i = 0; i < vliw->next_slot; ++i) + { + if (vliw->major[i] < FR550_MAJOR_M_1 || vliw->major[i] > FR550_MAJOR_M_5) + continue; + + /* Found a media insn, however, MNOP and MCLRACC don't count. */ + if (CGEN_INSN_NUM (vliw->insn[i]) == FRV_INSN_MNOP + || CGEN_INSN_NUM (vliw->insn[i]) == FRV_INSN_MCLRACC_0 + || CGEN_INSN_NUM (vliw->insn[i]) == FRV_INSN_MCLRACC_1) + continue; + + return TRUE; /* Found one. */ + } + + return FALSE; +} + +static bfd_boolean +fr550_find_float_in_vliw (FRV_VLIW *vliw) +{ + int i; + + for (i = 0; i < vliw->next_slot; ++i) + { + if (vliw->major[i] < FR550_MAJOR_F_1 || vliw->major[i] > FR550_MAJOR_F_4) + continue; + + /* Found a floating point insn, however, FNOP doesn't count. */ + if (CGEN_INSN_NUM (vliw->insn[i]) == FRV_INSN_FNOP) + continue; + + return TRUE; /* Found one. */ + } + + return FALSE; +} + +static bfd_boolean +fr550_check_insn_major_constraints (FRV_VLIW *vliw, + CGEN_ATTR_VALUE_ENUM_TYPE major, + const CGEN_INSN *insn) +{ + CGEN_ATTR_VALUE_ENUM_TYPE unit; + CGEN_ATTR_VALUE_ENUM_TYPE slot = (*vliw->current_vliw)[vliw->next_slot]; + switch (slot) + { + case UNIT_I2: + /* If it's a store, then there must be another store in I1 */ + unit = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_UNIT); + if (unit == UNIT_STORE) + return find_unit_in_vliw (vliw, UNIT_STORE); + break; + case UNIT_FM2: + case UNIT_FM3: + /* Floating point insns other than FNOP in slot f2 or f3 cannot coexist + with media insns. */ + if (major >= FR550_MAJOR_F_1 && major <= FR550_MAJOR_F_4 + && CGEN_INSN_NUM (insn) != FRV_INSN_FNOP) + return ! fr550_find_media_in_vliw (vliw); + /* Media insns other than MNOP in slot m2 or m3 cannot coexist with + floating point insns. */ + if (major >= FR550_MAJOR_M_1 && major <= FR550_MAJOR_M_5 + && CGEN_INSN_NUM (insn) != FRV_INSN_MNOP) + return ! fr550_find_float_in_vliw (vliw); + /* F-2 in slot f2 or f3 cannot coexist with F-2 or F-4 in slot f1 or f2 + respectively. */ + if (major == FR550_MAJOR_F_2) + return ! find_major_in_slot (vliw, FR550_MAJOR_F_2, + slot - (UNIT_FM2 - UNIT_FM0)) + && ! find_major_in_slot (vliw, FR550_MAJOR_F_4, + slot - (UNIT_FM2 - UNIT_FM0)); + /* M-2 or M-5 in slot m2 or m3 cannot coexist with M-2 in slot m1 or m2 + respectively. */ + if (major == FR550_MAJOR_M_2 || major == FR550_MAJOR_M_5) + return ! find_major_in_slot (vliw, FR550_MAJOR_M_2, + slot - (UNIT_FM2 - UNIT_FM0)); + /* M-4 in slot m2 or m3 cannot coexist with M-4 in slot m1 or m2 + respectively. */ + if (major == FR550_MAJOR_M_4) + return ! find_major_in_slot (vliw, FR550_MAJOR_M_4, + slot - (UNIT_FM2 - UNIT_FM0)); + break; + default: + break; + } + return TRUE; /* All OK. */ +} + +static bfd_boolean +fr500_check_insn_major_constraints (FRV_VLIW *vliw, CGEN_ATTR_VALUE_ENUM_TYPE major) +{ + /* TODO: A table might be faster for some of the more complex instances + here. */ + switch (major) + { + case FR500_MAJOR_I_1: + case FR500_MAJOR_I_4: + case FR500_MAJOR_I_5: + case FR500_MAJOR_I_6: + case FR500_MAJOR_B_1: + case FR500_MAJOR_B_2: + case FR500_MAJOR_B_3: + case FR500_MAJOR_B_4: + case FR500_MAJOR_B_5: + case FR500_MAJOR_B_6: + case FR500_MAJOR_F_4: + case FR500_MAJOR_F_8: + case FR500_MAJOR_M_8: + return TRUE; /* OK */ + case FR500_MAJOR_I_2: + /* Cannot coexist with I-3 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_I_3); + case FR500_MAJOR_I_3: + /* Cannot coexist with I-2 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_I_2); + case FR500_MAJOR_F_1: + case FR500_MAJOR_F_2: + /* Cannot coexist with F-5, F-6, or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_F_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_F_3: + /* Cannot coexist with F-7, or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_F_7) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_F_5: + /* Cannot coexist with F-1, F-2, F-6, F-7, or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_F_1) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_2) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_7) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_F_6: + /* Cannot coexist with F-1, F-2, F-5, F-6, or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_F_1) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_2) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_F_7: + /* Cannot coexist with F-3, F-5, F-7, or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_F_3) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_7) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_M_1: + /* Cannot coexist with M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_M_2: + case FR500_MAJOR_M_3: + /* Cannot coexist with M-5, M-6 or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_M_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_M_4: + /* Cannot coexist with M-6 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_M_6); + case FR500_MAJOR_M_5: + /* Cannot coexist with M-2, M-3, M-5, M-6 or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_M_2) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_3) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_M_6: + /* Cannot coexist with M-2, M-3, M-4, M-5, M-6 or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_M_2) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_3) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_4) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_M_7: + /* Cannot coexist with M-1, M-2, M-3, M-5, M-6 or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_M_1) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_2) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_3) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_1) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_2) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_3) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_7); + default: + fprintf (stderr, "frv-opc.c, line %d: bad major code, aborting.\n", + __LINE__); + abort (); + break; + } + return TRUE; +} + +static bfd_boolean +check_insn_major_constraints (FRV_VLIW *vliw, + CGEN_ATTR_VALUE_ENUM_TYPE major, + const CGEN_INSN *insn) +{ + switch (vliw->mach) + { + case bfd_mach_fr400: + return fr400_check_insn_major_constraints (vliw, major); + + case bfd_mach_fr450: + return fr450_check_insn_major_constraints (vliw, major); + + case bfd_mach_fr550: + return fr550_check_insn_major_constraints (vliw, major, insn); + + default: + return fr500_check_insn_major_constraints (vliw, major); + } +} + +/* Add in insn to the VLIW vliw if possible. + Return 0 if successful, non-zero otherwise. */ + +int +frv_vliw_add_insn (FRV_VLIW *vliw, const CGEN_INSN *insn) +{ + int index; + CGEN_ATTR_VALUE_ENUM_TYPE major; + CGEN_ATTR_VALUE_ENUM_TYPE unit; + VLIW_COMBO *new_vliw; + + if (vliw->constraint_violation || CGEN_INSN_INVALID_P (insn)) + return 1; + + index = vliw->next_slot; + if (index >= FRV_VLIW_SIZE) + return 1; + + unit = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_UNIT); + if (unit == UNIT_NIL) + { + fprintf (stderr, "frv-opc.c line %d: bad insn unit.\n", + __LINE__); + abort (); /* No UNIT specified for this insn in frv.cpu. */ + } + + switch (vliw->mach) + { + case bfd_mach_fr400: + major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR); + break; + case bfd_mach_fr450: + major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR450_MAJOR); + break; + case bfd_mach_fr550: + major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR550_MAJOR); + break; + default: + major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR); + break; + } + + if (index <= 0) + { + /* Any insn can be added to slot 0. */ + while (! match_unit (vliw, unit, (*vliw->current_vliw)[0])) + ++vliw->current_vliw; + vliw->major[0] = major; + vliw->insn[0] = insn; + vliw->next_slot = 1; + return 0; + } + + /* If there are already insns in the vliw(s) check to see that + this one can be added. Do this by finding an allowable vliw + combination that can accept the new insn. */ + if (! (vliw->elf_flags & EF_FRV_NOPACK)) + { + new_vliw = add_next_to_vliw (vliw, unit); + if (new_vliw && check_insn_major_constraints (vliw, major, insn)) + { + vliw->current_vliw = new_vliw; + vliw->major[index] = major; + vliw->insn[index] = insn; + vliw->next_slot++; + return 0; + } + + /* The frv machine supports all packing conbinations. If we fail, + to add the insn, then it could not be handled as if it was the fr500. + Just return as if it was handled ok. */ + if (vliw->mach == bfd_mach_frv) + return 0; + } + + vliw->constraint_violation = 1; + return 1; +} + +bfd_boolean +spr_valid (long regno) +{ + if (regno < 0) return FALSE; + if (regno <= 4095) return TRUE; + return FALSE; +} +/* -- */ + +/* -- asm.c */ +inline static const char * +parse_symbolic_address (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + int opinfo, + enum cgen_parse_operand_result *resultp, + bfd_vma *valuep) +{ + enum cgen_parse_operand_result result_type; + const char *errmsg = (* cd->parse_operand_fn) + (cd, CGEN_PARSE_OPERAND_SYMBOLIC, strp, opindex, opinfo, + &result_type, valuep); + + if (errmsg == NULL + && result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED) + return "symbolic expression required"; + + if (resultp) + *resultp = result_type; + + return errmsg; +} + +static const char * +parse_ldd_annotation (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + if (**strp == '#' || **strp == '%') + { + if (strncasecmp (*strp + 1, "tlsdesc(", 8) == 0) + { + *strp += 9; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_TLSDESC_RELAX, + &result_type, &value); + if (**strp != ')') + return "missing ')'"; + if (valuep) + *valuep = value; + ++*strp; + if (errmsg) + return errmsg; + } + } + + while (**strp == ' ' || **strp == '\t') + ++*strp; + + if (**strp != '@') + return "missing `@'"; + + ++*strp; + + return NULL; +} + +static const char * +parse_call_annotation (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + if (**strp == '#' || **strp == '%') + { + if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0) + { + *strp += 11; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GETTLSOFF_RELAX, + &result_type, &value); + if (**strp != ')') + return "missing ')'"; + if (valuep) + *valuep = value; + ++*strp; + if (errmsg) + return errmsg; + } + } + + while (**strp == ' ' || **strp == '\t') + ++*strp; + + if (**strp != '@') + return "missing `@'"; + + ++*strp; + + return NULL; +} + +static const char * +parse_ld_annotation (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + if (**strp == '#' || **strp == '%') + { + if (strncasecmp (*strp + 1, "tlsoff(", 7) == 0) + { + *strp += 8; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_TLSOFF_RELAX, + &result_type, &value); + if (**strp != ')') + return "missing ')'"; + if (valuep) + *valuep = value; + ++*strp; + if (errmsg) + return errmsg; + } + } + + while (**strp == ' ' || **strp == '\t') + ++*strp; + + if (**strp != '@') + return "missing `@'"; + + ++*strp; + + return NULL; +} + +static const char * +parse_ulo16 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + if (**strp == '#' || **strp == '%') + { + if (strncasecmp (*strp + 1, "lo(", 3) == 0) + { + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_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; + } + if (strncasecmp (*strp + 1, "gprello(", 8) == 0) + { + *strp += 9; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GPRELLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0) + { + *strp += 7; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0) + { + *strp += 15; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_FUNCDESC_GOTLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0) + { + *strp += 10; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTOFFLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0) + { + *strp += 18; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_FUNCDESC_GOTOFFLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0) + { + *strp += 14; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTTLSDESCLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0) + { + *strp += 11; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_TLSMOFFLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0) + { + *strp += 13; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTTLSOFFLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + } + return cgen_parse_unsigned_integer (cd, strp, opindex, valuep); +} + +static const char * +parse_uslo16 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + signed long *valuep) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + if (**strp == '#' || **strp == '%') + { + if (strncasecmp (*strp + 1, "lo(", 3) == 0) + { + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_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; + } + else if (strncasecmp (*strp + 1, "gprello(", 8) == 0) + { + *strp += 9; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GPRELLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0) + { + *strp += 7; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0) + { + *strp += 15; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_FUNCDESC_GOTLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0) + { + *strp += 10; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTOFFLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0) + { + *strp += 18; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_FUNCDESC_GOTOFFLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0) + { + *strp += 14; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTTLSDESCLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0) + { + *strp += 11; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_TLSMOFFLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0) + { + *strp += 13; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTTLSOFFLO, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + } + return cgen_parse_signed_integer (cd, strp, opindex, valuep); +} + +static const char * +parse_uhi16 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + if (**strp == '#' || **strp == '%') + { + if (strncasecmp (*strp + 1, "hi(", 3) == 0) + { + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16, + & result_type, & value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + { + /* If bfd_vma is wider than 32 bits, but we have a sign- + or zero-extension, truncate it. */ + if (value >= - ((bfd_vma)1 << 31) + || value <= ((bfd_vma)1 << 31) - (bfd_vma)1) + value &= (((bfd_vma)1 << 16) << 16) - 1; + value >>= 16; + } + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0) + { + *strp += 9; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GPRELHI, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gothi(", 6) == 0) + { + *strp += 7; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTHI, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotfuncdeschi(", 14) == 0) + { + *strp += 15; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_FUNCDESC_GOTHI, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotoffhi(", 9) == 0) + { + *strp += 10; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTOFFHI, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotofffuncdeschi(", 17) == 0) + { + *strp += 18; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_FUNCDESC_GOTOFFHI, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gottlsdeschi(", 13) == 0) + { + *strp += 14; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTTLSDESCHI, + &result_type, &value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "tlsmoffhi(", 10) == 0) + { + *strp += 11; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_TLSMOFFHI, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gottlsoffhi(", 12) == 0) + { + *strp += 13; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTTLSOFFHI, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + } + return cgen_parse_unsigned_integer (cd, strp, opindex, valuep); +} + +static long +parse_register_number (const char **strp) +{ + int regno; + + if (**strp < '0' || **strp > '9') + return -1; /* error */ + + regno = **strp - '0'; + for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp) + regno = regno * 10 + (**strp - '0'); + + return regno; +} + +static const char * +parse_spr (CGEN_CPU_DESC cd, + const char **strp, + CGEN_KEYWORD * table, + long *valuep) +{ + const char *save_strp; + long regno; + + /* Check for spr index notation. */ + if (strncasecmp (*strp, "spr[", 4) == 0) + { + *strp += 4; + regno = parse_register_number (strp); + if (**strp != ']') + return _("missing `]'"); + ++*strp; + if (! spr_valid (regno)) + return _("Special purpose register number is out of range"); + *valuep = regno; + return NULL; + } + + save_strp = *strp; + regno = parse_register_number (strp); + if (regno != -1) + { + if (! spr_valid (regno)) + return _("Special purpose register number is out of range"); + *valuep = regno; + return NULL; + } + + *strp = save_strp; + return cgen_parse_keyword (cd, strp, table, valuep); +} + +static const char * +parse_d12 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + long *valuep) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + /* Check for small data reference. */ + if (**strp == '#' || **strp == '%') + { + if (strncasecmp (*strp + 1, "gprel12(", 8) == 0) + { + *strp += 9; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GPREL12, + & result_type, & value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "got12(", 6) == 0) + { + *strp += 7; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOT12, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0) + { + *strp += 15; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_FUNCDESC_GOT12, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0) + { + *strp += 10; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTOFF12, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0) + { + *strp += 18; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_FUNCDESC_GOTOFF12, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0) + { + *strp += 14; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTTLSDESC12, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0) + { + *strp += 11; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_TLSMOFF12, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0) + { + *strp += 13; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTTLSOFF12, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + } + return cgen_parse_signed_integer (cd, strp, opindex, valuep); +} + +static const char * +parse_s12 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + long *valuep) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + /* Check for small data reference. */ + if (**strp == '#' || **strp == '%') + { + if (strncasecmp (*strp + 1, "gprel12(", 8) == 0) + { + *strp += 9; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GPREL12, + & result_type, & value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "got12(", 6) == 0) + { + *strp += 7; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOT12, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0) + { + *strp += 15; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_FUNCDESC_GOT12, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0) + { + *strp += 10; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTOFF12, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0) + { + *strp += 18; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_FUNCDESC_GOTOFF12, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0) + { + *strp += 14; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTTLSDESC12, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0) + { + *strp += 11; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_TLSMOFF12, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0) + { + *strp += 13; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GOTTLSOFF12, + & result_type, & value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + *valuep = value; + return errmsg; + } + } + + if (**strp == '#') + ++*strp; + return cgen_parse_signed_integer (cd, strp, opindex, valuep); +} + +static const char * +parse_u12 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + long *valuep) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + /* Check for small data reference. */ + if ((**strp == '#' || **strp == '%') + && strncasecmp (*strp + 1, "gprel12(", 8) == 0) + { + *strp += 9; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GPRELU12, + & result_type, & value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + *valuep = value; + return errmsg; + } + else + { + if (**strp == '#') + ++*strp; + return cgen_parse_signed_integer (cd, strp, opindex, valuep); + } +} + +static const char * +parse_A (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep, + unsigned long A) +{ + const char *errmsg; + + if (**strp == '#') + ++*strp; + + errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); + if (errmsg) + return errmsg; + + if (*valuep != A) + return _("Value of A operand must be 0 or 1"); + + return NULL; +} + +static const char * +parse_A0 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + return parse_A (cd, strp, opindex, valuep, 0); +} + +static const char * +parse_A1 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + return parse_A (cd, strp, opindex, valuep, 1); +} + +static const char * +parse_even_register (CGEN_CPU_DESC cd, + const char ** strP, + CGEN_KEYWORD * tableP, + long * valueP) +{ + const char * errmsg; + const char * saved_star_strP = * strP; + + errmsg = cgen_parse_keyword (cd, strP, tableP, valueP); + + if (errmsg == NULL && ((* valueP) & 1)) + { + errmsg = _("register number must be even"); + * strP = saved_star_strP; + } + + return errmsg; +} + +static const char * +parse_call_label (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + int opinfo, + enum cgen_parse_operand_result *resultp, + bfd_vma *valuep) +{ + const char *errmsg; + bfd_vma value; + + /* Check for small data reference. */ + if (opinfo == 0 && (**strp == '#' || **strp == '%')) + { + if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0) + { + *strp += 11; + errmsg = parse_symbolic_address (cd, strp, opindex, + BFD_RELOC_FRV_GETTLSOFF, + resultp, &value); + if (**strp != ')') + return _("missing `)'"); + ++*strp; + *valuep = value; + return errmsg; + } + } + + return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep); +} + +/* -- */ + +/* -- dis.c */ +static void +print_at (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long reloc_ann ATTRIBUTE_UNUSED, + long value ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + disassemble_info *info = (disassemble_info *) dis_info; + + (*info->fprintf_func) (info->stream, "@"); +} + +static void +print_spr (CGEN_CPU_DESC cd, + void * dis_info, + CGEN_KEYWORD *names, + long regno, + unsigned int attrs) +{ + /* Use the register index format for any unnamed registers. */ + if (cgen_keyword_lookup_value (names, regno) == NULL) + { + disassemble_info *info = (disassemble_info *) dis_info; + (*info->fprintf_func) (info->stream, "spr[%ld]", regno); + } + else + print_keyword (cd, dis_info, names, regno, attrs); +} + +static void +print_hi (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + disassemble_info *info = (disassemble_info *) dis_info; + + (*info->fprintf_func) (info->stream, value ? "0x%lx" : "hi(0x%lx)", value); +} + +static void +print_lo (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + disassemble_info *info = (disassemble_info *) dis_info; + if (value) + (*info->fprintf_func) (info->stream, "0x%lx", value); + else + (*info->fprintf_func) (info->stream, "lo(0x%lx)", value); +} + +/* -- */ diff --git a/cpu/iq10.cpu b/cpu/iq10.cpu new file mode 100644 index 00000000000..252cf5341f7 --- /dev/null +++ b/cpu/iq10.cpu @@ -0,0 +1,1112 @@ +; IQ10-only CPU description. -*- Scheme -*- +; +; Copyright 2001, 2002, 2007, 2009 Free Software Foundation, Inc. +; +; Contributed by Red Hat Inc; developed under contract from Vitesse. +; +; 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. + + +; Instructions. + +(dni andoui-q10 "iq10 and upper ones immediate" (MACH10 USES-RS USES-RT) + "andoui $rt,$rs,$hi16" + (+ OP10_ANDOUI rs rt hi16) + (set rt (and rs (or (sll hi16 16) #xFFFF))) + ()) + +(dni andoui2-q10 "iq10 and upper ones immediate" (ALIAS NO-DIS MACH10 USES-RS USES-RT) + "andoui ${rt-rs},$hi16" + (+ OP10_ANDOUI rt-rs hi16) + (set rt-rs (and rt-rs (or (sll hi16 16) #xFFFF))) + ()) + +(dni orui-q10 "or upper immediate" (MACH10 USES-RS USES-RT) + "orui $rt,$rs,$hi16" + (+ OP10_ORUI rs rt hi16) + (set rt (or rs (sll hi16 16))) + ()) + +(dni orui2-q10 "or upper immediate" (ALIAS NO-DIS MACH10 USES-RS USES-RT) + "orui ${rt-rs},$hi16" + (+ OP10_ORUI rt-rs hi16) + (set rt-rs (or rt-rs (sll hi16 16))) + ()) + +(dni mrgbq10 "merge bytes" (MACH10 USES-RD USES-RS USES-RT) + "mrgb $rd,$rs,$rt,$maskq10" + (+ OP_SPECIAL rs rt rd maskq10 FUNC_MRGB) + (sequence ((SI temp)) + (if (bitclear? mask 0) + (set temp (and rs #xFF)) + (set temp (and rt #xFF))) + (if (bitclear? mask 1) + (set temp (or temp (and rs #xFF00))) + (set temp (or temp (and rt #xFF00)))) + (if (bitclear? mask 2) + (set temp (or temp (and rs #xFF0000))) + (set temp (or temp (and rt #xFF0000)))) + (if (bitclear? mask 3) + (set temp (or temp (and rs #xFF000000))) + (set temp (or temp (and rt #xFF000000)))) + (set rd temp)) + ()) + +(dni mrgbq102 "merge bytes" (ALIAS NO-DIS MACH10 USES-RD USES-RS USES-RT) + "mrgb ${rd-rs},$rt,$maskq10" + (+ OP_SPECIAL rt rd-rs maskq10 FUNC_MRGB) + (sequence ((SI temp)) + (if (bitclear? mask 0) + (set temp (and rd-rs #xFF)) + (set temp (and rt #xFF))) + (if (bitclear? mask 1) + (set temp (or temp (and rd-rs #xFF00))) + (set temp (or temp (and rt #xFF00)))) + (if (bitclear? mask 2) + (set temp (or temp (and rd-rs #xFF0000))) + (set temp (or temp (and rt #xFF0000)))) + (if (bitclear? mask 3) + (set temp (or temp (and rd-rs #xFF000000))) + (set temp (or temp (and rt #xFF000000)))) + (set rd-rs temp)) + ()) + +; In the future, we'll want the j & jal to use the 21 bit target, with +; the upper five bits shifted up. For now, give 'em the 16 bit target. + +(dni jq10 "jump" (MACH10) + "j $jmptarg" + (+ OP_J (f-rs 0) (f-rt 0) jmptarg) +; "j $jmptargq10" +; (+ OP_J upper-5-jmptargq10 (f-rt 0) lower-16-jmptargq10) + (delay 1 (set pc jmptarg)) + ()) + +(dni jalq10 "jump and link" (MACH10 USES-RT) + "jal $rt,$jmptarg" + (+ OP_JAL (f-rs 0) rt jmptarg) +; "jal $rt,$jmptargq10" +; (+ OP_JAL upper-5-jmptargq10 rt lower-16-jmptargq10) + (delay 1 + (sequence () + (set rt (add pc 8)) + (set pc jmptarg))) + ()) + +(dni jalq10-2 "jump and link, implied r31" (MACH10 USES-RT) + "jal $jmptarg" + (+ OP_JAL (f-rs 0) (f-rt 31) jmptarg) + (delay 1 + (sequence () + (set rt (add pc 8)) + (set pc jmptarg))) + ()) + +; Branch instructions. + +(dni bbil "branch bit immediate likely" (MACH10 USES-RS) + "bbil $rs($bitnum),$offset" + (+ OP10_BBIL rs bitnum offset) + (if (bitset? rs bitnum) + (delay 1 (set pc offset)) + (skip 1)) + ()) + +(dni bbinl "branch bit immediate negated likely" (MACH10 USES-RS) + "bbinl $rs($bitnum),$offset" + (+ OP10_BBINL rs bitnum offset) + (if (bitclear? rs bitnum) + (delay 1 (set pc offset)) + (skip 1)) + ()) + +(dni bbvl "branch bit variable likely" (MACH10 USES-RS USES-RT) + "bbvl $rs,$rt,$offset" + (+ OP10_BBVL rs rt offset) + (if (bitset? rs (and rt #x1F)) + (delay 1 (set pc offset)) + (skip 1)) + ()) + +(dni bbvnl "branch bit variable negated likely" (MACH10 USES-RS USES-RT) + "bbvnl $rs,$rt,$offset" + (+ OP10_BBVNL rs rt offset) + (if (bitclear? rs (and rt #x1F)) + (delay 1 (set pc offset)) + (skip 1)) + ()) + +(dni bgtzal "branch if greater than zero and link" (MACH10 USES-RS USES-R31) + "bgtzal $rs,$offset" + (+ OP_REGIMM rs FUNC_BGTZAL offset) + (if (gt rs 0) + (sequence () + (set (reg h-gr 31) (add pc 8)) + (delay 1 (set pc offset)))) + ()) + +(dni bgtzall + "branch if greater than zero and link likely" (MACH10 USES-RS USES-R31) + "bgtzall $rs,$offset" + (+ OP_REGIMM rs FUNC_BGTZALL offset) + (if (gt rs 0) + (sequence () + (set (reg h-gr 31) (add pc 8)) + (delay 1 (set pc offset))) + (skip 1)) + ()) + +(dni blezal "branch if less than or equal to zero and link" (MACH10 USES-RS USES-R31) + "blezal $rs,$offset" + (+ OP_REGIMM rs FUNC_BLEZAL offset) + (if (le rs 0) + (sequence () + (set (reg h-gr 31) (add pc 8)) + (delay 1 (set pc offset)))) + ()) + +(dni blezall + "branch if less than or equal to zero and link likely" (MACH10 USES-RS USES-R31) + "blezall $rs,$offset" + (+ OP_REGIMM rs FUNC_BLEZALL offset) + (if (le rs 0) + (sequence () + (set (reg h-gr 31) (add pc 8)) + (delay 1 (set pc offset))) + (skip 1)) + ()) + +(dni bgtz-q10 "branch if greater than zero" (MACH10 USES-RS) + "bgtz $rs,$offset" + (+ OP_REGIMM rs FUNC_BGTZ offset) + (if (gt rs 0) + (delay 1 (set pc offset))) + ()) + +(dni bgtzl-q10 "branch if greater than zero likely" (MACH10 USES-RS) + "bgtzl $rs,$offset" + (+ OP_REGIMM rs FUNC_BGTZL offset) + (if (gt rs 0) + (delay 1 (set pc offset)) + (skip 1)) + ()) + + +(dni blez-q10 "branch if less than or equal to zero" (MACH10 USES-RS) + "blez $rs,$offset" + (+ OP_REGIMM rs FUNC_BLEZ offset) + (if (le rs 0) + (delay 1 (set pc offset))) + ()) + +(dni blezl-q10 "branch if less than or equal to zero likely" (MACH10 USES-RS) + "blezl $rs,$offset" + (+ OP_REGIMM rs FUNC_BLEZL offset) + (if (le rs 0) + (delay 1 (set pc offset)) + (skip 1)) + ()) + +(dni bmb-q10 "branch if matching byte-lane" (MACH10 USES-RS USES-RT) + "bmb $rs,$rt,$offset" + (+ OP10_BMB rs rt offset) + (sequence ((BI branch?)) + (set branch? 0) + (if (eq (and rs #xFF) (and rt #xFF)) + (set branch? 1)) + (if (eq (and rs #xFF00) (and rt #xFF00)) + (set branch? 1)) + (if (eq (and rs #xFF0000) (and rt #xFF0000)) + (set branch? 1)) + (if (eq (and rs #xFF000000) (and rt #xFF000000)) + (set branch? 1)) + (if branch? + (delay 1 (set pc offset)))) + ()) + +(dni bmbl "branch if matching byte-lane likely" (MACH10 USES-RS USES-RT) + "bmbl $rs,$rt,$offset" + (+ OP10_BMBL rs rt offset) + (sequence ((BI branch?)) + (set branch? 0) + (if (eq (and rs #xFF) (and rt #xFF)) + (set branch? 1)) + (if (eq (and rs #xFF00) (and rt #xFF00)) + (set branch? 1)) + (if (eq (and rs #xFF0000) (and rt #xFF0000)) + (set branch? 1)) + (if (eq (and rs #xFF000000) (and rt #xFF000000)) + (set branch? 1)) + (if branch? + (delay 1 (set pc offset)) + (skip 1))) + ()) + +(dni bri "branch if register invalid" (MACH10 USES-RS) + "bri $rs,$offset" + (+ OP_REGIMM rs FUNC_BRI offset) + (if (gt rs 0) + (delay 1 (set pc offset)) + (skip 1)) + ()) + +(dni brv "branch if register invalid" (MACH10 USES-RS) + "brv $rs,$offset" + (+ OP_REGIMM rs FUNC_BRV offset) + (if (gt rs 0) + (delay 1 (set pc offset)) + (skip 1)) + ()) + +; debug instructions + +(dni bctx "branch if the current context == instruction[21]" (MACH10 USES-RS) + "bctx $rs,$offset" + (+ OP_REGIMM rs FUNC_BCTX offset) + (delay 1 (set pc offset)) + ()) + +(dni yield "unconditional yield to the other context" (MACH10) + "yield" + (+ OP_SPECIAL (f-rs 0) (f-rt 0) (f-rd 0) (f-shamt 0) FUNC10_YIELD) + (unimp yield) + ()) + +; Special instructions. + +(dni crc32 "CRC, 32 bit input" (MACH10 USES-RD USES-RS USES-RT) + "crc32 $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 0) FUNC10_CRC32) + (unimp crc32) + ()) + +(dni crc32b "CRC, 8 bit input" (MACH10 USES-RD USES-RS USES-RT) + "crc32b $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 0) FUNC10_CRC32B) + (unimp crc32b) + ()) + +(dni cnt1s "Count ones" (MACH10 USES-RD USES-RS) + "cnt1s $rd,$rs" + (+ OP_SPECIAL rs rt rd (f-shamt 0) FUNC10_CNT1S) + (unimp crcp) + ()) + + +; Special Instructions + +(dni avail "Mark Header Buffer Available" (MACH10 USES-RD) + "avail $rd" + (+ OP_COP3 (f-rs 0) (f-rt 0) rd (f-shamt 0) FUNC10_AVAIL) + (unimp avail) + ()) + +(dni free "Mark Header Buffer Free" (MACH10 USES-RS USES-RD) + "free $rd,$rs" + (+ OP_COP3 rs (f-rt 0) rd (f-shamt 0) FUNC10_FREE) + (unimp free) + ()) + +(dni tstod "Test Header Buffer Order Dependency" (MACH10 USES-RS USES-RD) + "tstod $rd,$rs" + (+ OP_COP3 rs (f-rt 0) rd (f-shamt 0) FUNC10_TSTOD) + (unimp tstod) + ()) + +(dni cmphdr "Get a Complete Header" (MACH10 USES-RD) + "cmphdr $rd" + (+ OP_COP3 (f-rs 0) (f-rt 0) rd (f-shamt 0) FUNC10_CMPHDR) + (unimp cmphdr) + ()) + +(dni mcid "Allocate a Multicast ID" (MACH10 USES-RD USES-RT) + "mcid $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-shamt 0) FUNC10_MCID) + (unimp mcid) + ()) + +(dni dba "Allocate a Data Buffer Pointer" (MACH10 USES-RD) + "dba $rd" + (+ OP_COP3 (f-rs 0) (f-rt 0) rd (f-shamt 0) FUNC10_DBA) + (unimp dba) + ()) + +(dni dbd "Deallocate a Data Buffer Pointer" (MACH10 USES-RS USES-RT USES-RD) + "dbd $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 0) FUNC10_DBD) + (unimp dbd) + ()) + +(dni dpwt "DSTN_PORT Write" (MACH10 USES-RS USES-RD) + "dpwt $rd,$rs" + (+ OP_COP3 rs (f-rt 0) rd (f-shamt 0) FUNC10_DPWT) + (unimp dpwt) + ()) + +; Architectural and coprocessor instructions. + +(dni chkhdrq10 "" (MACH10 USES-RS USES-RD) + "chkhdr $rd,$rs" + (+ OP_COP3 rs (f-rt 0) rd (f-shamt 0) FUNC10_CHKHDR) + (unimp chkhdr) + ()) + +; Coprocessor DMA Instructions (IQ10) + +(dni rba "Read Bytes Absolute" (MACH10 USES-RS USES-RT USES-RD) + "rba $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 0) FUNC10_RBA) + (unimp rba) + ()) + +(dni rbal "Read Bytes Absolute and Lock" (MACH10 USES-RS USES-RT USES-RD) + "rbal $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 0) FUNC10_RBAL) + (unimp rbal) + ()) + +(dni rbar "Read Bytes Absolute and Release" (MACH10 USES-RS USES-RT USES-RD) + "rbar $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 0) FUNC10_RBAR) + (unimp rbar) + ()) + +(dni wba "Write Bytes Absolute" (MACH10 USES-RS USES-RT USES-RD) + "wba $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 0) FUNC10_WBA) + (unimp wba) + ()) + +(dni wbau "Write Bytes Absolute and Unlock" (MACH10 USES-RS USES-RT USES-RD) + "wbau $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 0) FUNC10_WBAU) + (unimp wbau) + ()) + +(dni wbac "Write Bytes Absolute Cacheable" (MACH10 USES-RS USES-RT USES-RD) + "wbac $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 0) FUNC10_WBAC) + (unimp wbac) + ()) + +(dni rbi "Read Bytes Immediate" (MACH10 USES-RD USES-RS USES-RT) + "rbi $rd,$rs,$rt,$bytecount" + (+ OP_COP3 rs rt rd FUNC10_RBI bytecount) + (unimp rbi) + ()) + +(dni rbil "Read Bytes Immediate and Lock" (MACH10 USES-RD USES-RS USES-RT) + "rbil $rd,$rs,$rt,$bytecount" + (+ OP_COP3 rs rt rd FUNC10_RBIL bytecount) + (unimp rbil) + ()) + +(dni rbir "Read Bytes Immediate and Release" (MACH10 USES-RD USES-RS USES-RT) + "rbir $rd,$rs,$rt,$bytecount" + (+ OP_COP3 rs rt rd FUNC10_RBIR bytecount) + (unimp rbir) + ()) + +(dni wbi "Write Bytes Immediate" (MACH10 USES-RD USES-RS USES-RT) + "wbi $rd,$rs,$rt,$bytecount" + (+ OP_COP3 rs rt rd FUNC10_WBI bytecount) + (unimp wbi) + ()) + +(dni wbic "Write Bytes Immediate Cacheable" (MACH10 USES-RD USES-RS USES-RT) + "wbic $rd,$rs,$rt,$bytecount" + (+ OP_COP3 rs rt rd FUNC10_WBIC bytecount) + (unimp wbic) + ()) + +(dni wbiu "Write Bytes Immediate" (MACH10 USES-RD USES-RS USES-RT) + "wbiu $rd,$rs,$rt,$bytecount" + (+ OP_COP3 rs rt rd FUNC10_WBIU bytecount) + (unimp wbiu) + ()) + +(dni pkrli "Packet Release Immediate" (MACH10 USES-RD USES-RS USES-RT) + "pkrli $rd,$rs,$rt,$bytecount" + (+ OP_COP2 rs rt rd FUNC10_PKRLI bytecount) + (unimp pkrli) + ()) + +(dni pkrlih "Packet Release Immediate and Hold" (MACH10 USES-RD USES-RS USES-RT) + "pkrlih $rd,$rs,$rt,$bytecount" + (+ OP_COP2 rs rt rd FUNC10_PKRLIH bytecount) + (unimp pkrlih) + ()) + +(dni pkrliu "Packet Release Immediate Unconditional" (MACH10 USES-RD USES-RS USES-RT) + "pkrliu $rd,$rs,$rt,$bytecount" + (+ OP_COP2 rs rt rd FUNC10_PKRLIU bytecount) + (unimp pkrliu) + ()) + +(dni pkrlic "Packet Release Immediate Continue" (MACH10 USES-RD USES-RS USES-RT) + "pkrlic $rd,$rs,$rt,$bytecount" + (+ OP_COP2 rs rt rd FUNC10_PKRLIC bytecount) + (unimp pkrlic) + ()) + +(dni pkrla "Packet Release Absolute" (MACH10 USES-RS USES-RT USES-RD) + "pkrla $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 0) FUNC10_PKRLA) + (unimp pkrla) + ()) + +(dni pkrlau "Packet Release Absolute Unconditional" (MACH10 USES-RS USES-RT USES-RD) + "pkrlau $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 0) FUNC10_PKRLAU) + (unimp pkrlau) + ()) + +(dni pkrlah "Packet Release Absolute and Hold" (MACH10 USES-RS USES-RT USES-RD) + "pkrlah $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 0) FUNC10_PKRLAH) + (unimp pkrlah) + ()) + +(dni pkrlac "Packet Release Absolute Continue" (MACH10 USES-RS USES-RT USES-RD) + "pkrlac $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 0) FUNC10_PKRLAC) + (unimp pkrlac) + ()) + +; Main Memory Access Instructions + +(dni lock "lock memory" (MACH10 USES-RD USES-RT) + "lock $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-shamt 0) FUNC10_LOCK) + (unimp lock) + ()) + +(dni unlk "unlock memory" (MACH10 USES-RT USES-RD) + "unlk $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-shamt 0) FUNC10_UNLK) + (unimp unlk) + ()) + +(dni swrd "Single Word Read" (MACH10 USES-RT USES-RD) + "swrd $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-shamt 0) FUNC10_SWRD) + (unimp swrd) + ()) + +(dni swrdl "Single Word Read and Lock" (MACH10 USES-RT USES-RD) + "swrdl $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-shamt 0) FUNC10_SWRDL) + (unimp swrdl) + ()) + +(dni swwr "Single Word Write" (MACH10 USES-RS USES-RT USES-RD) + "swwr $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 0) FUNC10_SWWR) + (unimp swwr) + ()) + +(dni swwru "Single Word Write and Unlock" (MACH10 USES-RS USES-RT USES-RD) + "swwru $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 0) FUNC10_SWWRU) + (unimp swwru) + ()) + +(dni dwrd "Double Word Read" (MACH10 EVEN-REG-NUM USES-RT USES-RD) + "dwrd $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-shamt 0) FUNC10_DWRD) + (unimp dwrd) + ()) + +(dni dwrdl "Double Word Read and Lock" (MACH10 EVEN-REG-NUM USES-RT USES-RD) + "dwrdl $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-shamt 0) FUNC10_DWRDL) + (unimp dwrdl) + ()) + +; CAM access instructions (IQ10) + +(dni cam36 "CAM Access in 36-bit Mode" (MACH10 USES-RT USES-RD) + "cam36 $rd,$rt,${cam-z},${cam-y}" + (+ OP_COP3 (f-rs 0) rt rd FUNC10_CAM36 cam-z cam-y) + (unimp cam36) + ()) + +(dni cam72 "CAM Access in 72-bit Mode" (MACH10 USES-RT USES-RD) + "cam72 $rd,$rt,${cam-y},${cam-z}" + (+ OP_COP3 (f-rs 0) rt rd FUNC10_CAM72 cam-z cam-y) + (unimp cam72) + ()) + +(dni cam144 "CAM Access in 144-bit Mode" (MACH10 USES-RT USES-RD) + "cam144 $rd,$rt,${cam-y},${cam-z}" + (+ OP_COP3 (f-rs 0) rt rd FUNC10_CAM144 cam-z cam-y) + (unimp cam144) + ()) + +(dni cam288 "CAM Access in 288-bit Mode" (MACH10 USES-RT USES-RD) + "cam288 $rd,$rt,${cam-y},${cam-z}" + (+ OP_COP3 (f-rs 0) rt rd FUNC10_CAM288 cam-z cam-y) + (unimp cam288) + ()) + +; Counter manager instructions (IQ10) + +(dni cm32and "Counter Manager And" (MACH10 USES-RS USES-RT USES-RD) + "cm32and $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM32AND) + (unimp cm32and) + ()) + +(dni cm32andn "Counter Manager And With Inverse" (MACH10 USES-RS USES-RT USES-RD) + "cm32andn $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM32ANDN) + (unimp cm32andn) + ()) + +(dni cm32or "Counter Manager Or" (MACH10 USES-RS USES-RT USES-RD) + "cm32or $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM32OR) + (unimp cm32or) + ()) + +(dni cm32ra "Counter Manager 32-bit Rolling Add" (MACH10 USES-RS USES-RT USES-RD) + "cm32ra $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 2) FUNC10_CM32RA) + (unimp cm32ra) + ()) + +(dni cm32rd "Counter Manager 32-bit Rolling Decrement" (MACH10 USES-RT USES-RD) + "cm32rd $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM32RD) + (unimp cm32rd) + ()) + +(dni cm32ri "Counter Manager 32-bit Rolling Increment" (MACH10 USES-RT USES-RD) + "cm32ri $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM32RI) + (unimp cm32ri) + ()) + +(dni cm32rs "Counter Manager 32-bit Rolling Subtract" (MACH10 USES-RS USES-RT USES-RD) + "cm32rs $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-shamt 2) FUNC10_CM32RS) + (unimp cm32rs) + ()) + +(dni cm32sa "Counter Manager 32-bit Saturating Add" (MACH10 USES-RS USES-RT USES-RD) + "cm32sa $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM32SA) + (unimp cm32sa) + ()) + +(dni cm32sd "Counter Manager 32-bit Saturating Decrement" (MACH10 USES-RT USES-RD) + "cm32sd $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM32SD) + (unimp cm32sd) + ()) + +(dni cm32si "Counter Manager 32-bit Saturating Increment" (MACH10 USES-RT USES-RD) + "cm32si $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM32SI) + (unimp cm32si) + ()) + +(dni cm32ss "Counter Manager 32-bit Saturating Subtract" (MACH10 USES-RS USES-RT USES-RD) + "cm32ss $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM32SS) + (unimp cm32ss) + ()) + +(dni cm32xor "Counter Manager Xor" (MACH10 USES-RS USES-RT USES-RD) + "cm32xor $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM32XOR) + (unimp cm32xor) + ()) + +(dni cm64clr "Counter Manager Clear" (MACH10 EVEN-REG-NUM USES-RT USES-RD) + "cm64clr $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM64CLR) + (unimp cm64clr) + ()) + +(dni cm64ra "Counter Manager 64-bit Rolling Add" (MACH10 EVEN-REG-NUM USES-RS USES-RT USES-RD) + "cm64ra $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM64RA) + (unimp cm64ra) + ()) + +(dni cm64rd "Counter Manager 64-bit Rolling Decrement" (MACH10 EVEN-REG-NUM USES-RT USES-RD) + "cm64rd $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM64RD) + (unimp cm64rd) + ()) + +(dni cm64ri "Counter Manager 32-bit Rolling Increment" (MACH10 EVEN-REG-NUM USES-RT USES-RD) + "cm64ri $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM64RI) + (unimp cm64ri) + ()) + +(dni cm64ria2 "Counter Manager 32/32 Rolling Increment/Add" (MACH10 EVEN-REG-NUM USES-RS USES-RT USES-RD) + "cm64ria2 $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM64RIA2) + (unimp cm64ria2) + ()) + +(dni cm64rs "Counter Manager 64-bit Rolling Subtract" (MACH10 EVEN-REG-NUM USES-RS USES-RT USES-RD) + "cm64rs $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM64RS) + (unimp cm64rs) + ()) + +(dni cm64sa "Counter Manager 64-bit Saturating Add" (MACH10 EVEN-REG-NUM USES-RS USES-RT USES-RD) + "cm64sa $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM64SA) + (unimp cm64sa) + ()) + +(dni cm64sd "Counter Manager 64-bit Saturating Decrement" (MACH10 EVEN-REG-NUM USES-RT USES-RD) + "cm64sd $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM64SD) + (unimp cm64sd) + ()) + +(dni cm64si "Counter Manager 64-bit Saturating Increment" (MACH10 EVEN-REG-NUM USES-RT USES-RD) + "cm64si $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM64SI) + (unimp cm64si) + ()) + +(dni cm64sia2 "Counter Manager 32/32 Saturating Increment/Add" (MACH10 EVEN-REG-NUM USES-RS USES-RT USES-RD) + "cm64sia2 $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM64SIA2) + (unimp cm64sia2) + ()) + +(dni cm64ss "Counter Manager 64-bit Saturating Subtract" (MACH10 EVEN-REG-NUM USES-RS USES-RT USES-RD) + "cm64ss $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM64SS) + (unimp cm64ss) + ()) + +(dni cm128ria2 "Counter Manager 128-bit 64/64 Rolling Increment/Add" (MACH10 EVEN-REG-NUM USES-RS USES-RT USES-RD) + "cm128ria2 $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM128RIA2) + (unimp cm128ria2) + ()) + +(dni cm128ria3 "Counter Manager 128-bit 32/32/64 Rolling Increment/Add" (MACH10 EVEN-REG-NUM USES-RS USES-RT USES-RD) + "cm128ria3 $rd,$rs,$rt,${cm-3z}" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM128RIA3 cm-3z) + (unimp cm128ria3) + ()) + +(dni cm128ria4 "Counter Manager 128-bit 32/32/32/32 Rolling Inc/Add" (MACH10 USES-RS USES-RT USES-RD) + "cm128ria4 $rd,$rs,$rt,${cm-4z}" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM128RIA4 cm-4z) + (unimp cm128ria4) + ()) + +(dni cm128sia2 "Counter Manager 128-bit 64/64 Saturating Inc/Add" (MACH10 EVEN-REG-NUM USES-RS USES-RT USES-RD) + "cm128sia2 $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM128SIA2) + (unimp cm128sia2) + ()) + +(dni cm128sia3 "Counter Manager 128-bit 32/32/64 Saturating Inc/Add" (MACH10 EVEN-REG-NUM USES-RS USES-RT USES-RD) + "cm128sia3 $rd,$rs,$rt,${cm-3z}" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM128SIA3 cm-3z) + (unimp cm128sia3) + ()) + +(dni cm128sia4 "Counter Manager 128-bit 32/32/32/32 Saturating Inc/Add" (MACH10 USES-RS USES-RT USES-RD) + "cm128sia4 $rd,$rs,$rt,${cm-4z}" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM128SIA4 cm-4z) + (unimp cm128sia4) + ()) + +(dni cm128vsa "Counter Manager Continuous State Dual Leaky Token Bucket Policing" (MACH10 USES-RS USES-RT USES-RD) + "cm128vsa $rd,$rs,$rt" + (+ OP_COP3 rs rt rd (f-cp-op 0) (f-cp-grp 2) FUNC10_CM128VSA) + (unimp cm128vsa) + ()) + +; Coprocessor Data Movement Instructions + +; Note that we don't set the USES-RD or USES-RT attributes for many of the following +; instructions, as it's the COP register that's being specified. + +; ??? Is YIELD-INSN the right attribute for IQ10? The IQ2000 used the attribute to warn about +; yielding instructions in a delay slot, but that's not relevant in IQ10. What *is* relevant +; (and unique to IQ10) is instructions that yield if the destination register is accessed +; before the value is there, causing a yield. + +(dni cfc "copy from coprocessor control register" (MACH10 LOAD-DELAY USES-RD YIELD-INSN) + "cfc $rd,$rt" + (+ OP_COP3 (f-rs 0) rt rd (f-shamt 0) FUNC10_CFC) + (unimp cfc) + ()) + +(dni ctc "copy to coprocessor control register" (MACH10 USES-RS) + "ctc $rs,$rt" + (+ OP_COP3 rs rt (f-rd 0) (f-shamt 0) FUNC10_CTC) + (unimp ctc) + ()) + +; Macros + +(dnmi m-avail "Mark Header Buffer Available" (MACH10 NO-DIS) + "avail" + (emit avail (f-rd 0)) +) + +(dnmi m-cam36 "CAM Access in 36-bit Mode" (MACH10 USES-RT USES-RD NO-DIS) + "cam36 $rd,$rt,${cam-z}" + (emit cam36 rd rt cam-z (f-cam-y 0)) +) + +(dnmi m-cam72 "CAM Access in 72-bit Mode" (MACH10 USES-RT USES-RD NO-DIS) + "cam72 $rd,$rt,${cam-z}" + (emit cam72 rd rt cam-z (f-cam-y 0)) +) + +(dnmi m-cam144 "CAM Access in 144-bit Mode" (MACH10 USES-RT USES-RD NO-DIS) + "cam144 $rd,$rt,${cam-z}" + (emit cam144 rd rt cam-z (f-cam-y 0)) +) + +(dnmi m-cam288 "CAM Access in 288-bit Mode" (MACH10 USES-RT USES-RD NO-DIS) + "cam288 $rd,$rt,${cam-z}" + (emit cam288 rd rt cam-z (f-cam-y 0)) +) + +(dnmi m-cm32read "Counter Manager 32-bit Rolling Add R0" (MACH10 USES-RT USES-RD NO-DIS) + "cm32read $rd,$rt" + (emit cm32ra rd (f-rs 0) rt) +) + +(dnmi m-cm64read "Counter Manager 64-bit Rolling Add R0" (MACH10 USES-RT USES-RD NO-DIS) + "cm64read $rd,$rt" + (emit cm64ra rd (f-rs 0) rt) +) + +(dnmi m-cm32mlog "Counter Manager 32-bit or R0" (MACH10 USES-RS USES-RT NO-DIS) + "cm32mlog $rs,$rt" + (emit cm32or (f-rd 0) rs rt) +) + +(dnmi m-cm32and "Counter Manager And" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm32and $rs,$rt" + (emit cm32and (f-rd 0) rs rt) +) + +(dnmi m-cm32andn "Counter Manager And With Inverse" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm32andn $rs,$rt" + (emit cm32andn (f-rd 0) rs rt) +) + +(dnmi m-cm32or "Counter Manager Or" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm32or $rs,$rt" + (emit cm32or (f-rd 0) rs rt) +) + +(dnmi m-cm32ra "Counter Manager 32-bit Rolling Add" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm32ra $rs,$rt" + (emit cm32ra (f-rd 0) rs rt) +) + +(dnmi m-cm32rd "Counter Manager 32-bit Rolling Decrement" (MACH10 USES-RT USES-RD NO-DIS) + "cm32rd $rt" + (emit cm32rd (f-rd 0) rt) +) + +(dnmi m-cm32ri "Counter Manager 32-bit Rolling Increment" (MACH10 USES-RT USES-RD NO-DIS) + "cm32ri $rt" + (emit cm32ri (f-rd 0) rt) +) + +(dnmi m-cm32rs "Counter Manager 32-bit Rolling Subtract" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm32rs $rs,$rt" + (emit cm32rs (f-rd 0) rs rt) +) + +(dnmi m-cm32sa "Counter Manager 32-bit Saturating Add" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm32sa $rs,$rt" + (emit cm32sa (f-rd 0) rs rt) +) + +(dnmi m-cm32sd "Counter Manager 32-bit Saturating Decrement" (MACH10 USES-RT USES-RD NO-DIS) + "cm32sd $rt" + (emit cm32sd (f-rd 0) rt) +) + +(dnmi m-cm32si "Counter Manager 32-bit Saturating Increment" (MACH10 USES-RT USES-RD NO-DIS) + "cm32si $rt" + (emit cm32si (f-rd 0) rt) +) + +(dnmi m-cm32ss "Counter Manager 32-bit Saturating Subtract" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm32ss $rs,$rt" + (emit cm32ss (f-rd 0) rs rt) +) + +(dnmi m-cm32xor "Counter Manager Xor" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm32xor $rs,$rt" + (emit cm32xor (f-rd 0) rs rt) +) + +(dnmi m-cm64clr "Counter Manager Clear" (MACH10 USES-RT USES-RD NO-DIS) + "cm64clr $rt" + (emit cm64clr (f-rd 0) rt) +) + +(dnmi m-cm64ra "Counter Manager 64-bit Rolling Add" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm64ra $rs,$rt" + (emit cm64ra (f-rd 0) rs rt) +) + +(dnmi m-cm64rd "Counter Manager 64-bit Rolling Decrement" (MACH10 USES-RT USES-RD NO-DIS) + "cm64rd $rt" + (emit cm64rd (f-rd 0) rt) +) + +(dnmi m-cm64ri "Counter Manager 32-bit Rolling Increment" (MACH10 USES-RT USES-RD NO-DIS) + "cm64ri $rt" + (emit cm64ri (f-rd 0) rt) +) + +(dnmi m-cm64ria2 "Counter Manager 32/32 Rolling Increment/Add" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm64ria2 $rs,$rt" + (emit cm64ria2 (f-rd 0) rs rt) +) + +(dnmi m-cm64rs "Counter Manager 64-bit Rolling Subtract" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm64rs $rs,$rt" + (emit cm64rs (f-rd 0) rs rt) +) + +(dnmi m-cm64sa "Counter Manager 64-bit Saturating Add" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm64sa $rs,$rt" + (emit cm64sa (f-rd 0) rs rt) +) + +(dnmi m-cm64sd "Counter Manager 64-bit Saturating Decrement" (MACH10 USES-RT USES-RD NO-DIS) + "cm64sd $rt" + (emit cm64sd (f-rd 0) rt) +) + +(dnmi m-cm64si "Counter Manager 64-bit Saturating Increment" (MACH10 USES-RT USES-RD NO-DIS) + "cm64si $rt" + (emit cm64si (f-rd 0) rt) +) + +(dnmi m-cm64sia2 "Counter Manager 32/32 Saturating Increment/Add" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm64sia2 $rs,$rt" + (emit cm64sia2 (f-rd 0) rs rt) +) + +(dnmi m-cm64ss "Counter Manager 64-bit Saturating Subtract" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm64ss $rs,$rt" + (emit cm64ss (f-rd 0) rs rt) +) + +(dnmi m-cm128ria2 "Counter Manager 128-bit 64/64 Rolling Increment/Add" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm128ria2 $rs,$rt" + (emit cm128ria2 (f-rd 0) rs rt) +) + +(dnmi m-cm128ria3 "Counter Manager 128-bit 32/32/64 Rolling Increment/Add" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm128ria3 $rs,$rt,${cm-3z}" + (emit cm128ria3 (f-rd 0) rs rt cm-3z) +) + +(dnmi m-cm128ria4 "Counter Manager 128-bit 32/32/32/32 Rolling Inc/Add" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm128ria4 $rs,$rt,${cm-4z}" + (emit cm128ria4 (f-rd 0) rs rt cm-4z) +) + +(dnmi m-cm128sia2 "Counter Manager 128-bit 64/64 Saturating Inc/Add" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm128sia2 $rs,$rt" + (emit cm128sia2 (f-rd 0) rs rt) +) + +(dnmi m-cm128sia3 "Counter Manager 128-bit 32/32/64 Saturating Inc/Add" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm128sia3 $rs,$rt,${cm-3z}" + (emit cm128sia3 (f-rd 0) rs rt cm-3z) +) + +(dnmi m-cm128sia4 "Counter Manager 128-bit 32/32/32/32 Saturating Inc/Add" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "cm128sia4 $rs,$rt,${cm-4z}" + (emit cm128sia4 (f-rd 0) rs rt cm-4z) +) + +(dnmi m-cmphdr "Get a Complete Header" (MACH10 NO-DIS) + "cmphdr" + (emit cmphdr (f-rd 0)) +) + +(dnmi m-dbd "Deallocate a Data Buffer Pointer" (MACH10 USES-RD USES-RT NO-DIS) + "dbd $rd,$rt" + (emit dbd rd (f-rs 0) rt) +) + +(dnmi m2-dbd "Deallocate a Data Buffer Pointer" (MACH10 USES-RT NO-DIS) + "dbd $rt" + (emit dbd (f-rd 0) (f-rs 0) rt) +) + +(dnmi m-dpwt "DSTN_PORT Write" (MACH10 USES-RS NO-DIS) + "dpwt $rs" + (emit dpwt (f-rd 0) rs) +) + +(dnmi m-free "" (MACH10 USES-RS USES-RD NO-DIS) + "free $rs" + (emit free (f-rd 0) rs) +) + +;(dnmi m-jal "jump and link, implied r31" (MACH10 USES-RT NO-DIS) +; "jal $jmptarg" +; (emit jal (f-rt 31) jmptarg) +;) + +(dnmi m-lock "lock memory" (MACH10 USES-RT NO-DIS) + "lock $rt" + (emit lock (f-rd 0) rt) +) + +(dnmi m-pkrla "Packet Release Absolute" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "pkrla $rs,$rt" + (emit pkrla (f-rd 0) rs rt) +) + +(dnmi m-pkrlac "Packet Release Absolute Continue" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "pkrlac $rs,$rt" + (emit pkrlac (f-rd 0) rs rt) +) + +(dnmi m-pkrlah "Packet Release Absolute and Hold" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "pkrlah $rs,$rt" + (emit pkrlah (f-rd 0) rs rt) +) + +(dnmi m-pkrlau "Packet Release Absolute Unconditional" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "pkrlau $rs,$rt" + (emit pkrlau (f-rd 0) rs rt) +) + +(dnmi m-pkrli "Packet Release Immediate" (MACH10 USES-RD USES-RS USES-RT NO-DIS) + "pkrli $rs,$rt,$bytecount" + (emit pkrli (f-rd 0) rs rt bytecount) +) + +(dnmi m-pkrlic "Packet Release Immediate Continue" (MACH10 USES-RS USES-RT NO-DIS) + "pkrlic $rs,$rt,$bytecount" + (emit pkrlic (f-rd 0) rs rt bytecount) +) + +(dnmi m-pkrlih "Packet Release Immediate and Hold" (MACH10 USES-RD USES-RS USES-RT NO-DIS) + "pkrlih $rs,$rt,$bytecount" + (emit pkrlih (f-rd 0) rs rt bytecount) +) + +(dnmi m-pkrliu "Packet Release Immediate Unconditional" (MACH10 USES-RD USES-RS USES-RT NO-DIS) + "pkrliu $rs,$rt,$bytecount" + (emit pkrliu (f-rd 0) rs rt bytecount) +) + +(dnmi m-rba "Read Bytes Absolute" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "rba $rs,$rt" + (emit rba (f-rd 0) rs rt) +) + +(dnmi m-rbal "Read Bytes Absolute and Lock" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "rbal $rs,$rt" + (emit rbal (f-rd 0) rs rt) +) + +(dnmi m-rbar "Read Bytes Absolute and Release" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "rbar $rs,$rt" + (emit rbar (f-rd 0) rs rt) +) + +(dnmi m-rbi "Read Bytes Immediate" (MACH10 USES-RS USES-RT NO-DIS) + "rbi $rs,$rt,$bytecount" + (emit rbi (f-rd 0) rs rt bytecount) +) + +(dnmi m-rbil "Read Bytes Immediate and Lock" (MACH10 USES-RS USES-RT NO-DIS) + "rbil $rs,$rt,$bytecount" + (emit rbil (f-rd 0) rs rt bytecount) +) + +(dnmi m-rbir "Read Bytes Immediate and Release" (MACH10 USES-RS USES-RT NO-DIS) + "rbir $rs,$rt,$bytecount" + (emit rbir (f-rd 0) rs rt bytecount) +) + +(dnmi m-swwr "Single Word Write" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "swwr $rs,$rt" + (emit swwr (f-rd 0) rs rt) +) + +(dnmi m-swwru "Single Word Write and Unlock" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "swwru $rs,$rt" + (emit swwru (f-rd 0) rs rt) +) + +(dnmi m-tstod "Test Header Buffer Order Dependency" (MACH10 USES-RS USES-RD NO-DIS) + "tstod $rs" + (emit tstod (f-rd 0) rs) +) + +(dnmi m-unlk "" (MACH10 USES-RT USES-RD NO-DIS) + "unlk $rt" + (emit unlk (f-rd 0) rt) +) + +(dnmi m-wba "Write Bytes Absolute" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "wba $rs,$rt" + (emit wba (f-rd 0) rs rt) +) + +(dnmi m-wbac "Write Bytes Absolute Cacheable" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "wbac $rs,$rt" + (emit wbac (f-rd 0) rs rt) +) + +(dnmi m-wbau "Write Bytes Absolute and Unlock" (MACH10 USES-RS USES-RT USES-RD NO-DIS) + "wbau $rs,$rt" + (emit wbau (f-rd 0) rs rt) +) + +(dnmi m-wbi "Write Bytes Immediate" (MACH10 USES-RD USES-RS USES-RT NO-DIS) + "wbi $rs,$rt,$bytecount" + (emit wbi (f-rd 0) rs rt bytecount) +) + +(dnmi m-wbic "Write Bytes Immediate Cacheable" (MACH10 USES-RD USES-RS USES-RT NO-DIS) + "wbic $rs,$rt,$bytecount" + (emit wbic (f-rd 0) rs rt bytecount) +) + +(dnmi m-wbiu "Write Bytes Immediate" (MACH10 USES-RD USES-RS USES-RT NO-DIS) + "wbiu $rs,$rt,$bytecount" + (emit wbiu (f-rd 0) rs rt bytecount) +) + diff --git a/cpu/iq2000.cpu b/cpu/iq2000.cpu new file mode 100644 index 00000000000..e25ba69392b --- /dev/null +++ b/cpu/iq2000.cpu @@ -0,0 +1,1196 @@ +; IQ2000/IQ10 Common CPU description. -*- Scheme -*- +; Copyright 2001, 2002, 2007, 2009 Free Software Foundation, Inc. +; +; Contributed by Red Hat Inc; developed under contract from Fujitsu. +; +; 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 iq2000) + (comment "IQ2000 architecture") + (insn-lsb0? #t) + (machs iq2000 iq10) + (isas iq2000) +) + +(define-isa + (name iq2000) + (comment "Basic IQ2000 instruction set") + (default-insn-word-bitsize 32) + (default-insn-bitsize 32) + (base-insn-bitsize 32) + (decode-assist (31 30 29 28 27 26)) +) + +(define-cpu + (name iq2000bf) + (comment "IQ2000 family") + (endian big) + (word-bitsize 32) + (file-transform "") +) + +(define-cpu + (name iq10bf) + (comment "IQ10 coprocessor family") + (endian big) + (word-bitsize 32) + (file-transform "") + +) + +(define-mach + (name iq2000) + (comment "IQ2000 packet processing engine") + (cpu iq2000bf) + (isas iq2000) +) + +(define-mach + (name iq10) + (comment "IQ10 coprocessor") + (cpu iq10bf) + (isas iq2000) +) + +(define-model + (name iq2000) + (comment "IQ2000 microprocessor") + (mach iq2000) + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () () () ()) +) + +(define-model + (name iq10) + (comment "IQ10 coprocessor") + (mach iq10) + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () () () ()) +) + +; Macros to simplify MACH attribute specification. + +(define-pmacro MACH2000 (MACH iq2000)) +(define-pmacro MACH10 (MACH iq10)) + + +; Hardware elements. + +(define-hardware + (name h-pc) + (comment "program counter") + (attrs PC PROFILE (ISA iq2000)) + (type pc) + (get () (c-call USI "get_h_pc")) + (set (newval) (c-call VOID "set_h_pc" newval)) +) +; FIXME: it would be nice if the hardwired zero in R0 could be +; specified as a virtual hardware element, with one less register in +; the register file proper. + +(define-keyword + (name gr-names) + (print-name h-gr) + (values (r0 0) (%0 0) (r1 1) (%1 1) (r2 2) (%2 2) (r3 3) (%3 3) + (r4 4) (%4 4) (r5 5) (%5 5) (r6 6) (%6 6) (r7 7) (%7 7) + (r8 8) (%8 8) (r9 9) (%9 9) (r10 10) (%10 10) (r11 11) (%11 11) + (r12 12) (%12 12) (r13 13) (%13 13) (r14 14) (%14 14) (r15 15) (%15 15) + (r16 16) (%16 16) (r17 17) (%17 17) (r18 18) (%18 18) (r19 19) (%19 19) + (r20 20) (%20 20) (r21 21) (%21 21) (r22 22) (%22 22) (r23 23) (%23 23) + (r24 24) (%24 24) (r25 25) (%25 25) (r26 26) (%26 26) (r27 27) (%27 27) + (r28 28) (%28 28) (r29 29) (%29 29) (r30 30) (%30 30) (r31 31) (%31 31)) +) + +(define-hardware + (name h-gr) + (comment "General purpose registers") +; (attrs (ISA iq2000) CACHE-ADDR) + (type register SI (32)) + (indices extern-keyword gr-names) + (get (idx) + (cond SI + ((eq idx 0) (const 0)) + (else (raw-reg h-gr idx)))) + (set (idx newval) + (cond VOID + ((eq idx 0) (nop)) + (else (set (raw-reg h-gr idx) newval)))) +) + + +; Instruction fields. + +(dnf f-opcode "opcode field" () 31 6) +(dnf f-rs "register field Rs" () 25 5) +(dnf f-rt "register field Rt" () 20 5) +(dnf f-rd "register field Rd" () 15 5) +(dnf f-shamt "shift amount field" () 10 5) +(dnf f-cp-op "coprocessor op field" () 10 3) +(dnf f-cp-op-10 "coprocessor op field for CAM" () 10 5) +(dnf f-cp-grp "coprocessor group field" () 7 2) +(dnf f-func "function field" () 5 6) +(dnf f-imm "immediate field" () 15 16) + +(define-multi-ifield + (name f-rd-rs) + (comment "register Rd implied from Rs") + (attrs) + (mode UINT) + (subfields f-rd f-rs) + (insert (sequence () + (set (ifield f-rd) (ifield f-rd-rs)) + (set (ifield f-rs) (ifield f-rd-rs)) + )) + (extract (sequence () + (set (ifield f-rd-rs) (ifield f-rs)) + )) +) + +(define-multi-ifield + (name f-rd-rt) + (comment "register Rd implied from Rt") + (attrs) + (mode UINT) + (subfields f-rd f-rt) + (insert (sequence () + (set (ifield f-rd) (ifield f-rd-rt)) + (set (ifield f-rt) (ifield f-rd-rt)) + )) + (extract (sequence () + (set (ifield f-rd-rt) (ifield f-rt)) + )) +) + +(define-multi-ifield + (name f-rt-rs) + (comment "register Rt implied from Rs") + (attrs) + (mode UINT) + (subfields f-rt f-rs) + (insert (sequence () + (set (ifield f-rt) (ifield f-rt-rs)) + (set (ifield f-rs) (ifield f-rt-rs)) + )) + (extract (sequence () + (set (ifield f-rd-rs) (ifield f-rs)) + )) +) + +(df f-jtarg "jump target field" (ABS-ADDR) 15 16 UINT + ((value pc) (srl USI (and USI value #x03FFFF) 2)) + ((value pc) (or USI (and USI pc #xF0000000) (sll USI value 2)))) + +(df f-jtargq10 "iq10 jump target field" (ABS-ADDR) 20 21 UINT + ((value pc) (srl SI (and SI value #x7FFFFF) 2)) + ((value pc) (or SI (and SI pc #xF0000000) (sll SI value 2)))) + +(df f-offset "pc offset field" (PCREL-ADDR) 15 16 INT + ; Actually, this is relative to the address of the delay slot. + ((value pc) (sra SI (sub SI value pc) 2)) + ((value pc) (add SI (sll SI value 2) (add pc 4)))) + +; Instruction fields that scarcely appear in instructions. + +(dnf f-count "count field" () 15 7) +(dnf f-bytecount "byte count field" () 7 8) +(dnf f-index "index field" () 8 9) +(dnf f-mask "mask field" () 9 4) +(dnf f-maskq10 "iq10 mask field" () 10 5) +(dnf f-maskl "mask left field" () 4 5) +(dnf f-excode "execcode field" () 25 20) +(dnf f-rsrvd "reserved field" () 25 10) +(dnf f-10-11 "bits 10:0" () 10 11) +(dnf f-24-19 "bits 24:6" () 24 19) +(dnf f-5 "bit 5" () 5 1) +(dnf f-10 "bit 10" () 10 1) +(dnf f-25 "bit 25" () 25 1) +(dnf f-cam-z "cam global mask z" () 5 3) +(dnf f-cam-y "cam operation y" () 2 3) +(dnf f-cm-3func "CM 3 bit fn field" () 5 3) +(dnf f-cm-4func "CM 4 bit fn field" () 5 4) +(dnf f-cm-3z "CM 3Z field" () 1 2) +(dnf f-cm-4z "CM 4Z field" () 2 3) + + +; Enumerations. + +(define-normal-insn-enum + opcodes "primary opcodes" () OP_ f-opcode + (("SPECIAL" 0) ("REGIMM" 1) ("J" 2) ("JAL" 3) ("BEQ" 4) ("BNE" 5) ("BLEZ" 6) ("BGTZ" 7) + ("ADDI" 8) ("ADDIU" 9) ("SLTI" 10) ("SLTIU" 11) ("ANDI" 12) ("ORI" 13) ("XORI" 14) ("LUI" 15) + ("COP0" 16) ("COP1" 17) ("COP2" 18) ("COP3" 19) ("BEQL" 20) ("BNEL" 21) ("BLEZL" 22) ("BGTZL" 23) + ("BMB0" 24) ("BMB1" 25) ("BMB2" 26) ("BMB3" 27) ("BBI" 28) ("BBV" 29) ("BBIN" 30) ("BBVN" 31) + ("LB" 32) ("LH" 33) ("LW" 35) ("LBU" 36) ("LHU" 37) ("RAM" 39) + ("SB" 40) ("SH" 41) ("SW" 43) ("ANDOI" 44) ("BMB" 45) ("ORUI" 47) + ("LDW" 48) + ("SDW" 56) ("ANDOUI" 63)) +) + +(define-normal-insn-enum + q10_opcodes "iq10-only primary opcodes" () OP10_ f-opcode + (("BMB" 6) ("ORUI" 15) ("BMBL" 22) ("ANDOUI" 47) ("BBIL" 60) ("BBVL" 61) ("BBINL" 62) ("BBVNL" 63)) +) + +(define-normal-insn-enum + regimm-functions "branch sub-opcodes" () FUNC_ f-rt + (("BLTZ" 0) ("BGEZ" 1) ("BLTZL" 2) ("BGEZL" 3) ("BLEZ" 4) ("BGTZ" 5) ("BLEZL" 6) ("BGTZL" 7) + ("BRI" 8) ("BRV" 9) ("BCTX" 12) + ("BLTZAL" 16) ("BGEZAL" 17) ("BLTZALL" 18) ("BGEZALL" 19) ("BLEZAL" 20) ("BGTZAL" 21) ("BLEZALL" 22) ("BGTZALL" 23)) +) + +(define-normal-insn-enum + functions "function sub-opcodes" () FUNC_ f-func + (("SLL" 0) ("SLMV" 1) ("SRL" 2) ("SRA" 3) ("SLLV" 4) ("SRMV" 5) ("SRLV" 6) ("SRAV" 7) + ("JR" 8) ("JALR" 9) ("JCR" 10) ("SYSCALL" 12) ("BREAK" 13) ("SLEEP" 14) + ("ADD" 32) ("ADDU" 33) ("SUB" 34) ("SUBU" 35) ("AND" 36) ("OR" 37) ("XOR" 38) ("NOR" 39) + ("ADO16" 41) ("SLT" 42) ("SLTU" 43) ("MRGB" 45)) +) + +; iq10 special function sub-opcodes +(define-normal-insn-enum + q10s_functions "iq10-only special function sub-opcodes" () FUNC10_ f-func + (("YIELD" 14) ("CNT1S" 46)) +) + +; coprocessor opcodes in concert with f-cp-grp +(define-normal-insn-enum + cop_functions "iq10 function sub-opcodes" () FUNC10_ f-func + (("CFC" 0) ("LOCK" 1) ("CTC" 2) ("UNLK" 3) ("SWRD" 4) ("SWRDL" 5) ("SWWR" 6) ("SWWRU" 7) + ("RBA" 8) ("RBAL" 9) ("RBAR" 10) ("DWRD" 12) ("DWRDL" 13) + ("WBA" 16) ("WBAU" 17) ("WBAC" 18) ("CRC32" 20) ("CRC32B" 21) + ("MCID" 32) ("DBD" 33) ("DBA" 34) ("DPWT" 35) ("AVAIL" 36) ("FREE" 37) ("CHKHDR" 38) ("TSTOD" 39) + ("PKRLA" 40) ("PKRLAU" 41) ("PKRLAH" 42) ("PKRLAC" 43) ("CMPHDR" 44) + + ("CM64RS" 0) ("CM64RD" 1) ("CM64RI" 4) ("CM64CLR" 5) + ("CM64SS" 8) ("CM64SD" 9) ("CM64SI" 12) + ("CM64RA" 16) ("CM64RIA2" 20) ("CM128RIA2" 21) + ("CM64SA" 24) ("CM64SIA2" 28) ("CM128SIA2" 29) + ("CM32RS" 32) ("CM32RD" 33) ("CM32XOR" 34) ("CM32ANDN" 35) ("CM32RI" 36) ("CM128VSA" 38) + ("CM32SS" 40) ("CM32SD" 41) ("CM32OR" 42) ("CM32AND" 43) ("CM32SI" 44) + ("CM32RA" 48) + ("CM32SA" 56) ) +) + +; coprocessor opcodes in concert with f-cp-grp +(define-normal-insn-enum + cop_cm128_4functions "iq10 function sub-opcodes" () FUNC10_ f-cm-4func + (("CM128RIA3" 4) ("CM128SIA3" 6)) +) + +(define-normal-insn-enum + cop_cm128_3functions "iq10 function sub-opcodes" () FUNC10_ f-cm-3func + (("CM128RIA4" 6) ("CM128SIA4" 7)) +) + +(define-normal-insn-enum + cop2_functions "iq10 coprocessor sub-opcodes" () FUNC10_ f-cp-op + (("PKRLI" 0) ("PKRLIU" 1) ("PKRLIH" 2) ("PKRLIC" 3) ("RBIR" 1) ("RBI" 2) ("RBIL" 3) ("WBIC" 5) ("WBI" 6) ("WBIU" 7)) +) + +(define-normal-insn-enum + cop3_cam_functions "iq10 coprocessor cam sub-opcodes" () FUNC10_ f-cp-op-10 + (("CAM36" 16) ("CAM72" 17) ("CAM144" 18) ("CAM288" 19)) +) + + +; Attributes. + +(define-attr + (for insn) + (type boolean) + (name YIELD-INSN) + (comment "insn generates a context yield") +) + +(define-attr + (for insn) + (type boolean) + (name LOAD-DELAY) + (comment "insn has a load delay") +) + +(define-attr + (for insn) + (type boolean) + (name EVEN-REG-NUM) + (comment "insn requires an even numbered register in rt(2000) or rd(10)") +) + +(define-attr + (for insn) + (type boolean) + (name UNSUPPORTED) + (comment "insn is unsupported") +) + +(define-pmacro (define-reg-use-attr regfield) + (define-attr + (for insn) + (type boolean) + (name (.sym USES- (.upcase regfield))) + (comment ("insn accesses register operand " regfield)))) + +(define-reg-use-attr "rd") +(define-reg-use-attr "rs") +(define-reg-use-attr "rt") +(define-reg-use-attr "r31") + + +; Operands. + +(dnop rs "register Rs" () h-gr f-rs) +(dnop rt "register Rt" () h-gr f-rt) +(dnop rd "register Rd" () h-gr f-rd) +(dnop rd-rs "register Rd from Rs" () h-gr f-rd-rs) +(dnop rd-rt "register Rd from Rt" () h-gr f-rd-rt) +(dnop rt-rs "register Rt from Rs" () h-gr f-rt-rs) +(dnop shamt "shift amount" () h-uint f-shamt) +(define-operand (name imm) (comment "immediate") (attrs) + (type h-uint) (index f-imm) (handlers (parse "imm"))) +(dnop offset "pc-relative offset" () h-iaddr f-offset) +(dnop baseoff "base register offset" () h-iaddr f-imm) +(dnop jmptarg "jump target" () h-iaddr f-jtarg) +(dnop mask "mask" () h-uint f-mask) +(dnop maskq10 "iq10 mask" () h-uint f-maskq10) +(dnop maskl "mask left" () h-uint f-maskl) +(dnop count "count" () h-uint f-count) +(dnop _index "index" () h-uint f-index) +(dnop execode "execcode" () h-uint f-excode) +(dnop bytecount "byte count" () h-uint f-bytecount) +(dnop cam-y "cam global opn y" () h-uint f-cam-y) +(dnop cam-z "cam global mask z" () h-uint f-cam-z) +(dnop cm-3func "CM 3 bit fn field" () h-uint f-cm-3func) +(dnop cm-4func "CM 4 bit fn field" () h-uint f-cm-4func) +(dnop cm-3z "CM 3 bit Z field" () h-uint f-cm-3z) +(dnop cm-4z "CM 4 bit Z field" () h-uint f-cm-4z) + +; Aliases for the rs and rt operands. This just makes the load/store +; insns easier to compare with the instruction set documentation. + +(dnop base "base register" () h-gr f-rs) +(dnop maskr "mask right" () h-uint f-rs) +(dnop bitnum "bit number" () h-uint f-rt) + +; For high(foo). +(define-operand + (name hi16) + (comment "high 16 bit immediate") + (attrs) + (type h-uint) + (index f-imm) + (handlers (parse "hi16")) +) + +; For low(foo). +(define-operand + (name lo16) + (comment "16 bit signed immediate, for low") + (attrs) + (type h-uint) + (index f-imm) + (handlers (parse "lo16")) +) + +; For negated imm. +(define-operand + (name mlo16) + (comment "negated 16 bit signed immediate") + (attrs) + (type h-uint) + (index f-imm) + (handlers (parse "mlo16")) +) + +; For iq10 jmps +; In the future, we'll want the j & jal to use the 21 bit target, with +; the upper five bits shifted up. For now, don't use this. +(define-operand + (name jmptargq10) + (comment "iq10 21-bit jump offset") + (attrs) + (type h-iaddr) + (index f-jtargq10) + (handlers (parse "jtargq10")) +) + + +; Instructions. + +; A pmacro for use in semantic bodies of unimplemented insns. +(define-pmacro (unimp mnemonic) (nop)) + +(define-pmacro (bitset? value bit-num) + (and value (sll 1 bit-num))) + +(define-pmacro (bitclear? value bit-num) + (not (bitset? value bit-num))) + +; Arithmetic/logic instructions. + +(dni add2 "add registers" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "add ${rd-rs},$rt" + (+ OP_SPECIAL rt rd-rs (f-shamt 0) FUNC_ADD) + (set rd-rs (add rt rd-rs)) + ()) + +(dni add "add registers" (USES-RD USES-RS USES-RT) + "add $rd,$rs,$rt" + (+ OP_SPECIAL rs rt rd (f-shamt 0) FUNC_ADD) + (set rd (add rs rt)) + ()) + + +(dni addi2 "add immediate" (ALIAS NO-DIS USES-RS USES-RT) + "addi ${rt-rs},$lo16" + (+ OP_ADDI rt-rs lo16) + (set rt-rs (add rt-rs (ext SI (trunc HI lo16)))) + ()) + +(dni addi "add immediate" (USES-RS USES-RT) + "addi $rt,$rs,$lo16" + (+ OP_ADDI rs rt lo16) + (set rt (add rs (ext SI (trunc HI lo16)))) + ()) + +(dni addiu2 "add immediate unsigned" (ALIAS NO-DIS USES-RS USES-RT) + "addiu ${rt-rs},$lo16" + (+ OP_ADDIU rt-rs lo16) + (set rt-rs (add rt-rs (ext SI (trunc HI lo16)))) + ()) + +(dni addiu "add immediate unsigned" (USES-RS USES-RT) + "addiu $rt,$rs,$lo16" + (+ OP_ADDIU rs rt lo16) + (set rt (add rs (ext SI (trunc HI lo16)))) + ()) + +(dni addu2 "add unsigned" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "addu ${rd-rs},$rt" + (+ OP_SPECIAL rd-rs rt (f-shamt 0) FUNC_ADDU) + (set rd-rs (add rd-rs rt)) + ()) + +(dni addu "add unsigned" (USES-RD USES-RS USES-RT) + "addu $rd,$rs,$rt" + (+ OP_SPECIAL rs rt rd (f-shamt 0) FUNC_ADDU) + (set rd (add rs rt)) + ()) + +(dni ado162 "add 16, ones complement" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "ado16 ${rd-rs},$rt" + (+ OP_SPECIAL rd-rs rt (f-shamt 0) FUNC_ADO16) + (sequence ((HI high) (HI low)) + (set low (add HI (and HI rd-rs #xFFFF) (and HI rt #xFFFF))) + (set high (add HI (srl rd-rs 16) (srl rt 16))) + (set rd-rs (or SI (sll SI high 16) low))) + ()) + +(dni ado16 "add 16, ones complement" (USES-RD USES-RS USES-RT) + "ado16 $rd,$rs,$rt" + (+ OP_SPECIAL rs rt rd (f-shamt 0) FUNC_ADO16) + (sequence ((HI high) (HI low)) + (set low (add HI (and HI rs #xFFFF) (and HI rt #xFFFF))) + (set high (add HI (srl rs 16) (srl rt 16))) + (set rd (or SI (sll SI high 16) low))) + ()) + +(dni and2 "and register" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "and ${rd-rs},$rt" + (+ OP_SPECIAL rd-rs rt (f-shamt 0) FUNC_AND) + (set rd-rs (and rd-rs rt)) + ()) + +(dni and "and register" (USES-RD USES-RS USES-RT) + "and $rd,$rs,$rt" + (+ OP_SPECIAL rs rt rd (f-shamt 0) FUNC_AND) + (set rd (and rs rt)) + ()) + +(dni andi2 "and immediate" (ALIAS NO-DIS USES-RS USES-RT) + "andi ${rt-rs},$lo16" + (+ OP_ANDI rt-rs lo16) + (set rt-rs (and rt-rs (zext SI lo16))) + ()) + +(dni andi "and immediate" (USES-RS USES-RT) + "andi $rt,$rs,$lo16" + (+ OP_ANDI rs rt lo16) + (set rt (and rs (zext SI lo16))) + ()) + +(dni andoi2 "and ones immediate" (ALIAS NO-DIS USES-RS USES-RT) + "andoi ${rt-rs},$lo16" + (+ OP_ANDOI rt-rs lo16) + (set rt-rs (and rt-rs (or #xFFFF0000 (ext SI (trunc HI lo16))))) + ()) + +(dni andoi "and ones immediate" (USES-RS USES-RT) + "andoi $rt,$rs,$lo16" + (+ OP_ANDOI rs rt lo16) + (set rt (and rs (or #xFFFF0000 (ext SI (trunc HI lo16))))) + ()) + +(dni nor2 "nor" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "nor ${rd-rs},$rt" + (+ OP_SPECIAL rd-rs rt (f-shamt 0) FUNC_NOR) + (set rd-rs (inv (or rd-rs rt))) + ()) + +(dni nor "nor" (USES-RD USES-RS USES-RT) + "nor $rd,$rs,$rt" + (+ OP_SPECIAL rs rt rd (f-shamt 0) FUNC_NOR) + (set rd (inv (or rs rt))) + ()) + +(dni or2 "or" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "or ${rd-rs},$rt" + (+ OP_SPECIAL rd-rs rt (f-shamt 0) FUNC_OR) + (set rd-rs (or rd-rs rt)) + ()) + +(dni or "or" (USES-RD USES-RS USES-RT) + "or $rd,$rs,$rt" + (+ OP_SPECIAL rs rt rd (f-shamt 0) FUNC_OR) + (set rd (or rs rt)) + ()) + +(dni ori2 "or immediate" (ALIAS NO-DIS USES-RS USES-RT) + "ori ${rt-rs},$lo16" + (+ OP_ORI rt-rs lo16) + (set rt-rs (or rt-rs (zext SI lo16))) + ()) + +(dni ori "or immediate" (USES-RS USES-RT) + "ori $rt,$rs,$lo16" + (+ OP_ORI rs rt lo16) + (set rt (or rs (zext SI lo16))) + ()) + +(dni ram "rotate and mask" (USES-RD USES-RT) + "ram $rd,$rt,$shamt,$maskl,$maskr" + (+ OP_RAM maskr rt rd shamt (f-5 0) maskl) + (sequence () + (set rd (ror rt shamt)) + (set rd (and rd (srl #xFFFFFFFF maskl))) + (set rd (and rd (sll #xFFFFFFFF maskr)))) + ()) + +(dni sll "shift left logical" (USES-RD USES-RT) + "sll $rd,$rt,$shamt" + (+ OP_SPECIAL (f-rs 0) rt rd shamt (f-func 0)) + (set rd (sll rt shamt)) + ()) + +(dni sllv2 "shift left logical variable" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "sllv ${rd-rt},$rs" + (+ OP_SPECIAL rs rd-rt (f-shamt 0) FUNC_SLLV) + (set rd-rt (sll rd-rt (and rs #x1F))) + ()) + +(dni sllv "shift left logical variable" (USES-RD USES-RS USES-RT) + "sllv $rd,$rt,$rs" + (+ OP_SPECIAL rs rt rd (f-shamt 0) FUNC_SLLV) + (set rd (sll rt (and rs #x1F))) + ()) + +(dni slmv2 "shift left and mask variable" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "slmv ${rd-rt},$rs,$shamt" + (+ OP_SPECIAL rs rd-rt shamt FUNC_SLMV) + (set rd-rt (and (sll rd-rt shamt) (srl #xFFFFFFFF rs))) + ()) + +(dni slmv "shift left and mask variable" (USES-RD USES-RS USES-RT) + "slmv $rd,$rt,$rs,$shamt" + (+ OP_SPECIAL rs rt rd shamt FUNC_SLMV) + (set rd (and (sll rt shamt) (srl #xFFFFFFFF rs))) + ()) + +(dni slt2 "set if less than" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "slt ${rd-rs},$rt" + (+ OP_SPECIAL rt rd-rs (f-shamt 0) FUNC_SLT) + (if (lt rd-rs rt) + (set rd-rs 1) + (set rd-rs 0)) + ()) + +(dni slt "set if less than" (USES-RD USES-RS USES-RT) + "slt $rd,$rs,$rt" + (+ OP_SPECIAL rs rt rd (f-shamt 0) FUNC_SLT) + (if (lt rs rt) + (set rd 1) + (set rd 0)) + ()) + +(dni slti2 "set if less than immediate" (ALIAS NO-DIS USES-RS USES-RT) + "slti ${rt-rs},$imm" + (+ OP_SLTI rt-rs imm) + (if (lt rt-rs (ext SI (trunc HI imm))) + (set rt-rs 1) + (set rt-rs 0)) + ()) + +(dni slti "set if less than immediate" (USES-RS USES-RT) + "slti $rt,$rs,$imm" + (+ OP_SLTI rs rt imm) + (if (lt rs (ext SI (trunc HI imm))) + (set rt 1) + (set rt 0)) + ()) + +(dni sltiu2 "set if less than immediate unsigned" (ALIAS NO-DIS USES-RS USES-RT) + "sltiu ${rt-rs},$imm" + (+ OP_SLTIU rt-rs imm) + (if (ltu rt-rs (ext SI (trunc HI imm))) + (set rt-rs 1) + (set rt-rs 0)) + ()) + +(dni sltiu "set if less than immediate unsigned" (USES-RS USES-RT) + "sltiu $rt,$rs,$imm" + (+ OP_SLTIU rs rt imm) + (if (ltu rs (ext SI (trunc HI imm))) + (set rt 1) + (set rt 0)) + ()) + +(dni sltu2 "set if less than unsigned" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "sltu ${rd-rs},$rt" + (+ OP_SPECIAL rd-rs rt (f-shamt 0) FUNC_SLTU) + (if (ltu rd-rs rt) + (set rd-rs 1) + (set rd-rs 0)) + ()) + +(dni sltu "set if less than unsigned" (USES-RD USES-RS USES-RT) + "sltu $rd,$rs,$rt" + (+ OP_SPECIAL rs rt rd (f-shamt 0) FUNC_SLTU) + (if (ltu rs rt) + (set rd 1) + (set rd 0)) + ()) + +(dni sra2 "shift right arithmetic" (ALIAS NO-DIS USES-RD USES-RT) + "sra ${rd-rt},$shamt" + (+ OP_SPECIAL (f-rs 0) rd-rt shamt FUNC_SRA) + (set rd-rt (sra rd-rt shamt)) + ()) + +(dni sra "shift right arithmetic" (USES-RD USES-RT) + "sra $rd,$rt,$shamt" + (+ OP_SPECIAL (f-rs 0) rt rd shamt FUNC_SRA) + (set rd (sra rt shamt)) + ()) + +(dni srav2 "shift right arithmetic variable" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "srav ${rd-rt},$rs" + (+ OP_SPECIAL rs rd-rt (f-shamt 0) FUNC_SRAV) + (set rd-rt (sra rd-rt (and rs #x1F))) + ()) + +(dni srav "shift right arithmetic variable" (USES-RD USES-RS USES-RT) + "srav $rd,$rt,$rs" + (+ OP_SPECIAL rs rt rd (f-shamt 0) FUNC_SRAV) + (set rd (sra rt (and rs #x1F))) + ()) + +(dni srl "shift right logical" (USES-RD USES-RT) + "srl $rd,$rt,$shamt" + (+ OP_SPECIAL (f-rs 0) rt rd shamt FUNC_SRL) + (set rd (srl rt shamt)) + ()) + +(dni srlv2 "shift right logical variable" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "srlv ${rd-rt},$rs" + (+ OP_SPECIAL rs rd-rt (f-shamt 0) FUNC_SRLV) + (set rd-rt (srl rd-rt (and rs #x1F))) + ()) + +(dni srlv "shift right logical variable" (USES-RD USES-RS USES-RT) + "srlv $rd,$rt,$rs" + (+ OP_SPECIAL rs rt rd (f-shamt 0) FUNC_SRLV) + (set rd (srl rt (and rs #x1F))) + ()) + +(dni srmv2 "shift right and mask variable" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "srmv ${rd-rt},$rs,$shamt" + (+ OP_SPECIAL rs rd-rt shamt FUNC_SRMV) + (set rd-rt (and (srl rd-rt shamt) (sll #xFFFFFFFF rs))) + ()) + +(dni srmv "shift right and mask variable" (USES-RD USES-RS USES-RT) + "srmv $rd,$rt,$rs,$shamt" + (+ OP_SPECIAL rs rt rd shamt FUNC_SRMV) + (set rd (and (srl rt shamt) (sll #xFFFFFFFF rs))) + ()) + +(dni sub2 "subtract" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "sub ${rd-rs},$rt" + (+ OP_SPECIAL rt rd-rs (f-shamt 0) FUNC_SUB) + (set rd-rs (sub rd-rs rt)) + ()) + +(dni sub "subtract" (USES-RD USES-RS USES-RT) + "sub $rd,$rs,$rt" + (+ OP_SPECIAL rs rt rd (f-shamt 0) FUNC_SUB) + (set rd (sub rs rt)) + ()) + +(dni subu2 "subtract unsigned" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "subu ${rd-rs},$rt" + (+ OP_SPECIAL rt rd-rs (f-shamt 0) FUNC_SUBU) + (set rd-rs (sub rd-rs rt)) + ()) + +(dni subu "subtract unsigned" (USES-RD USES-RS USES-RT) + "subu $rd,$rs,$rt" + (+ OP_SPECIAL rs rt rd (f-shamt 0) FUNC_SUBU) + (set rd (sub rs rt)) + ()) + +(dni xor2 "exclusive or" (ALIAS NO-DIS USES-RD USES-RS USES-RT) + "xor ${rd-rs},$rt" + (+ OP_SPECIAL rt rd-rs (f-shamt 0) FUNC_XOR) + (set rd-rs (xor rd-rs rt)) + ()) + +(dni xor "exclusive or" (USES-RD USES-RS USES-RT) + "xor $rd,$rs,$rt" + (+ OP_SPECIAL rs rt rd (f-shamt 0) FUNC_XOR) + (set rd (xor rs rt)) + ()) + +(dni xori2 "exclusive or immediate" (ALIAS NO-DIS USES-RS USES-RT) + "xori ${rt-rs},$lo16" + (+ OP_XORI rt-rs lo16) + (set rt-rs (xor rt-rs (zext SI lo16))) + ()) + +(dni xori "exclusive or immediate" (USES-RS USES-RT) + "xori $rt,$rs,$lo16" + (+ OP_XORI rs rt lo16) + (set rt (xor rs (zext SI lo16))) + ()) + + +; Branch instructions. + +(dni bbi "branch bit immediate" (USES-RS) + "bbi $rs($bitnum),$offset" + (+ OP_BBI rs bitnum offset) + (if (bitset? rs bitnum) + (delay 1 (set pc offset))) + ()) + +(dni bbin "branch bit immediate negated" (USES-RS) + "bbin $rs($bitnum),$offset" + (+ OP_BBIN rs bitnum offset) + (if (bitclear? rs bitnum) + (delay 1 (set pc offset))) + ()) + +(dni bbv "branch bit variable" (USES-RS USES-RT) + "bbv $rs,$rt,$offset" + (+ OP_BBV rs rt offset) + (if (bitset? rs (and rt #x1F)) + (delay 1 (set pc offset))) + ()) + +(dni bbvn "branch bit variable negated" (USES-RS USES-RT) + "bbvn $rs,$rt,$offset" + (+ OP_BBVN rs rt offset) + (if (bitclear? rs (and rt #x1F)) + (delay 1 (set pc offset))) + ()) + +(dni beq "branch if equal" (USES-RS USES-RT) + "beq $rs,$rt,$offset" + (+ OP_BEQ rs rt offset) + (if (eq rs rt) + (delay 1 (set pc offset))) + ()) + +(dni beql "branch if equal likely" (USES-RS USES-RT) + "beql $rs,$rt,$offset" + (+ OP_BEQL rs rt offset) + (if (eq rs rt) + (delay 1 (set pc offset)) + (skip 1)) + ()) + +(dni bgez "branch if greater than or equal to zero" (USES-RS) + "bgez $rs,$offset" + (+ OP_REGIMM rs FUNC_BGEZ offset) + (if (ge rs 0) + (delay 1 (set pc offset))) + ()) + +(dni bgezal "branch if greater than or equal to zero and link" (USES-RS USES-R31) + "bgezal $rs,$offset" + (+ OP_REGIMM rs FUNC_BGEZAL offset) + (if (ge rs 0) + (sequence () + (set (reg h-gr 31) (add pc 8)) + (delay 1 (set pc offset)))) + ()) + +(dni bgezall + "branch if greater than equal to zero and link likely" (USES-RS USES-R31) + "bgezall $rs,$offset" + (+ OP_REGIMM rs FUNC_BGEZALL offset) + (if (ge rs 0) + (sequence () + (set (reg h-gr 31) (add pc 8)) + (delay 1 (set pc offset))) + (skip 1)) + ()) + +(dni bgezl "branch if greater or equal to zero likely" (USES-RS) + "bgezl $rs,$offset" + (+ OP_REGIMM rs FUNC_BGEZL offset) + (if (ge rs 0) + (delay 1 (set pc offset)) + (skip 1)) + ()) + +(dni bltz "branch if less than zero" (USES-RS) + "bltz $rs,$offset" + (+ OP_REGIMM rs FUNC_BLTZ offset) + (if (lt rs 0) + (delay 1 (set pc offset))) + ()) + +(dni bltzl "branch if less than zero likely" (USES-RS) + "bltzl $rs,$offset" + (+ OP_REGIMM rs FUNC_BLTZL offset) + (if (lt rs 0) + (delay 1 (set pc offset)) + (skip 1)) + ()) + +(dni bltzal "branch if less than zero and link" (USES-RS USES-R31) + "bltzal $rs,$offset" + (+ OP_REGIMM rs FUNC_BLTZAL offset) + (if (lt rs 0) + (sequence () + (set (reg h-gr 31) (add pc 8)) + (delay 1 (set pc offset)))) + ()) + +(dni bltzall "branch if less than zero and link likely" (USES-RS USES-R31) + "bltzall $rs,$offset" + (+ OP_REGIMM rs FUNC_BLTZALL offset) + (if (lt rs 0) + (sequence () + (set (reg h-gr 31) (add pc 8)) + (delay 1 (set pc offset))) + (skip 1)) + ()) + +(dni bmb0 "branch if matching byte-lane 0" (USES-RS USES-RT) + "bmb0 $rs,$rt,$offset" + (+ OP_BMB0 rs rt offset) + (if (eq (and rs #xFF) (and rt #xFF)) + (delay 1 (set pc offset))) + ()) + +(dni bmb1 "branch if matching byte-lane 1" (USES-RS USES-RT) + "bmb1 $rs,$rt,$offset" + (+ OP_BMB1 rs rt offset) + (if (eq (and rs #xFF00) (and rt #xFF00)) + (delay 1 (set pc offset))) + ()) + +(dni bmb2 "branch if matching byte-lane 2" (USES-RS USES-RT) + "bmb2 $rs,$rt,$offset" + (+ OP_BMB2 rs rt offset) + (if (eq (and rs #xFF0000) (and rt #xFF0000)) + (delay 1 (set pc offset))) + ()) + +(dni bmb3 "branch if matching byte-lane 3" (USES-RS USES-RT) + "bmb3 $rs,$rt,$offset" + (+ OP_BMB3 rs rt offset) + (if (eq (and rs #xFF000000) (and rt #xFF000000)) + (delay 1 (set pc offset))) + ()) + +(dni bne "branch if not equal" (USES-RS USES-RT) + "bne $rs,$rt,$offset" + (+ OP_BNE rs rt offset) + (if (ne rs rt) + (delay 1 (set pc offset))) + ()) + +(dni bnel "branch if not equal likely" (USES-RS USES-RT) + "bnel $rs,$rt,$offset" + (+ OP_BNEL rs rt offset) + (if (ne rs rt) + (delay 1 (set pc offset)) + (skip 1)) + ()) + + + + +; Jump instructions. +; Might as well jump! + +(dni jalr "jump and link register" (USES-RD USES-RS) + "jalr $rd,$rs" + (+ OP_SPECIAL rs (f-rt 0) rd (f-shamt 0) FUNC_JALR) + (delay 1 + (sequence () + (set rd (add pc 8)) + (set pc rs))) + ()) + +(dni jr "jump register" (USES-RS) + "jr $rs" + (+ OP_SPECIAL rs (f-rt 0) (f-rd 0) (f-shamt 0) FUNC_JR) + (delay 1 (set pc rs)) + ()) + + +; Load instructions. + +(dni lb "load byte" (LOAD-DELAY USES-RS USES-RT) + "lb $rt,$lo16($base)" + (+ OP_LB base rt lo16) + (set rt (ext WI (mem QI (add base (ext SI (trunc HI lo16)))))) +; (sequence ((SI addr) (SI word)) +; (set addr (add base lo16)) +; (set word (mem SI (and addr (inv 3)))) +; (set word (srl word (sll (and addr 2) 3))) +; (set rt (ext SI word))) + ()) + +(dni lbu "load byte unsigned" (LOAD-DELAY USES-RS USES-RT) + "lbu $rt,$lo16($base)" + (+ OP_LBU base rt lo16) + (set rt (zext WI (mem QI (add base (ext SI (trunc HI lo16)))))) +; (sequence ((SI addr) (SI word)) +; (set addr (add base lo16)) +; (set word (mem SI (and addr (inv 3)))) +; (set rt (srl word (sll (and addr 2) 3)))) + ()) + +(dni lh "load half word" (LOAD-DELAY USES-RS USES-RT) + "lh $rt,$lo16($base)" + (+ OP_LH base rt lo16) + (set rt (ext WI (mem HI (add base (ext SI (trunc HI lo16)))))) +; (sequence ((SI addr) (HI word)) +; (set addr (add base lo16)) +; (set word (mem SI (and addr (inv 3)))) +; (set word (srl word (sll (and addr 1) 4))) +; (set rt (ext SI word))) + ()) + +(dni lhu "load half word unsigned" (LOAD-DELAY USES-RS USES-RT) + "lhu $rt,$lo16($base)" + (+ OP_LHU base rt lo16) + (set rt (zext WI (mem HI (add base (ext SI (trunc HI lo16)))))) +; (sequence ((SI addr) (SI word)) +; (set addr (add base lo16)) +; (set word (mem SI (and addr (inv 3)))) +; (set rt (srl word (sll (and addr 1) 4)))) + ()) + +(dni lui "load upper immediate" (USES-RT) + "lui $rt,$hi16" + (+ OP_LUI (f-rs 0) rt hi16) + (set rt (sll hi16 16)) + ()) + +(dni lw "load word" (LOAD-DELAY USES-RS USES-RT) + "lw $rt,$lo16($base)" + (+ OP_LW base rt lo16) + (set rt (mem SI (add base (ext SI (trunc HI lo16))))) + ()) + + +; Store instructions. + +(dni sb "store byte" (USES-RS USES-RT) + "sb $rt,$lo16($base)" + (+ OP_SB base rt lo16) + (set (mem QI (add base (ext SI (trunc HI lo16)))) (and QI rt #xFF)) + ()) + +(dni sh "store half word" (USES-RS USES-RT) + "sh $rt,$lo16($base)" + (+ OP_SH base rt lo16) + (set (mem HI (add base (ext SI (trunc HI lo16)))) (and HI rt #xFFFF)) + ()) + +(dni sw "store word" (USES-RS USES-RT) + "sw $rt,$lo16($base)" + (+ OP_SW base rt lo16) + (set (mem SI (add base (ext SI (trunc HI lo16)))) rt) + ()) + + +; Special instructions for simulation/debugging +(dni break "breakpoint" () + "break" + (+ OP_SPECIAL (f-rs 0) (f-rt 0) (f-rd 0) (f-shamt 0) FUNC_BREAK) + (c-call VOID "do_break" pc) + ()) + +(dni syscall "system call" (YIELD-INSN) + "syscall" + (+ OP_SPECIAL execode (f-func 12)) + (c-call VOID "do_syscall") + ()) + +; Macro instructions, common to iq10 & iq2000 + +(dnmi nop "nop" () + "nop" + (emit sll (rd 0) (rt 0) (shamt 0)) +) + +(dnmi li "load immediate" (USES-RS NO-DIS) + "li $rs,$imm" + (emit ori (rt 0) rs imm) +) + +(dnmi move "move" (USES-RD USES-RT NO-DIS) + "move $rd,$rt" + (emit or rd (rs 0) rt) +) + +(dnmi lb-base-0 "load byte - implied base 0" (USES-RT NO-DIS) + "lb $rt,$lo16" + (emit lb rt lo16 (base 0)) +) + +(dnmi lbu-base-0 "load byte unsigned - implied base 0" (USES-RT NO-DIS) + "lbu $rt,$lo16" + (emit lbu rt lo16 (base 0)) +) + +(dnmi lh-base-0 "load half - implied base 0" (USES-RT NO-DIS) + "lh $rt,$lo16" + (emit lh rt lo16 (base 0)) +) + +(dnmi lw-base-0 "load word - implied base 0" (USES-RT NO-DIS) + "lw $rt,$lo16" + (emit lw rt lo16 (base 0)) +) + +(dnmi m-add "add immediate" (USES-RS USES-RT NO-DIS) + "add $rt,$rs,$lo16" + (emit addi rt rs lo16)) + +(dnmi m-addu "add immediate unsigned" (USES-RS USES-RT NO-DIS) + "addu $rt,$rs,$lo16" + (emit addiu rt rs lo16) +) + +(dnmi m-and "and immediate" (USES-RS USES-RT NO-DIS) + "and $rt,$rs,$lo16" + (emit andi rt rs lo16) +) + +(dnmi m-j "jump register" (USES-RS NO-DIS) + "j $rs" + (emit jr rs) +) + +(dnmi m-or "or immediate" (USES-RS USES-RT NO-DIS) + "or $rt,$rs,$lo16" + (emit ori rt rs lo16) +) + +(dnmi m-sll "shift left logical" (USES-RD USES-RT USES-RS NO-DIS) + "sll $rd,$rt,$rs" + (emit sllv rd rt rs) +) + +(dnmi m-slt "slt immediate" (USES-RS USES-RT NO-DIS) + "slt $rt,$rs,$imm" + (emit slti rt rs imm) +) + +(dnmi m-sltu "sltu immediate" (USES-RS USES-RT NO-DIS) + "sltu $rt,$rs,$imm" + (emit sltiu rt rs imm) +) + +(dnmi m-sra "shift right arithmetic" (USES-RD USES-RT USES-RS NO-DIS) + "sra $rd,$rt,$rs" + (emit srav rd rt rs) +) + +(dnmi m-srl "shift right logical" (USES-RD USES-RT USES-RS NO-DIS) + "srl $rd,$rt,$rs" + (emit srlv rd rt rs) +) + +(dnmi not "not" (USES-RD USES-RT NO-DIS) + "not $rd,$rt" + (emit nor rd (rs 0) rt) +) + +(dnmi subi "sub immediate" (USES-RS USES-RT NO-DIS) + "subi $rt,$rs,$mlo16" + (emit addiu rt rs mlo16) +) + +(dnmi m-sub "subtract immediate" (USES-RS USES-RT NO-DIS) + "sub $rt,$rs,$mlo16" + (emit addiu rt rs mlo16) +) + +(dnmi m-subu "subtract unsigned" (USES-RS USES-RT NO-DIS) + "subu $rt,$rs,$mlo16" + (emit addiu rt rs mlo16) +) + +(dnmi sb-base-0 "store byte - implied base 0" (USES-RT NO-DIS) + "sb $rt,$lo16" + (emit sb rt lo16 (base 0)) +) + +(dnmi sh-base-0 "store half - implied base 0" (USES-RT NO-DIS) + "sh $rt,$lo16" + (emit sh rt lo16 (base 0)) +) + +(dnmi sw-base-0 "store word - implied base 0" (USES-RT NO-DIS) + "sw $rt,$lo16" + (emit sw rt lo16 (base 0)) +) + +(dnmi m-xor "xor immediate" (USES-RS USES-RT NO-DIS) + "xor $rt,$rs,$lo16" + (emit xori rt rs lo16) +) + + +(if (keep-mach? (iq2000)) +(include "iq2000m.cpu")) + +(if (keep-mach? (iq10)) +(include "iq10.cpu")) diff --git a/cpu/iq2000.opc b/cpu/iq2000.opc new file mode 100644 index 00000000000..f1803737370 --- /dev/null +++ b/cpu/iq2000.opc @@ -0,0 +1,320 @@ +/* IQ2000 opcode support. -*- C -*- + + Copyright 2000, 2001, 2002, 2005, 2007, 2009 Free Software Foundation, Inc. + + Contributed by Red Hat Inc; developed under contract from Fujitsu. + + 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. */ + +/* This file is an addendum to iq2000.cpu. Heavy use of C code isn't + appropriate in .cpu files, so it resides here. This especially applies + to assembly/disassembly where parsing/printing can be quite involved. + Such things aren't really part of the specification of the cpu, per se, + so .cpu files provide the general framework and .opc files handle the + nitty-gritty details as necessary. + + Each section is delimited with start and end markers. + + <arch>-opc.h additions use: "-- opc.h" + <arch>-opc.c additions use: "-- opc.c" + <arch>-asm.c additions use: "-- asm.c" + <arch>-dis.c additions use: "-- dis.c" + <arch>-ibd.h additions use: "-- ibd.h". */ + +/* -- opc.h */ + +/* Allows reason codes to be output when assembler errors occur. */ +#define CGEN_VERBOSE_ASSEMBLER_ERRORS + +/* Override disassembly hashing - there are variable bits in the top + byte of these instructions. */ +#define CGEN_DIS_HASH_SIZE 8 +#define CGEN_DIS_HASH(buf,value) (((* (unsigned char*) (buf)) >> 6) % CGEN_DIS_HASH_SIZE) + +/* following activates check beyond hashing since some iq2000 and iq10 + instructions have same mnemonics but different functionality. */ +#define CGEN_VALIDATE_INSN_SUPPORTED + +extern int iq2000_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *); + +/* -- asm.c */ + +#include "safe-ctype.h" + +static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'"); + +/* Special check to ensure that instruction exists for given machine. */ + +int +iq2000_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn) +{ + int machs = cd->machs; + + return (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH) & machs) != 0; +} + +static int +iq2000_cgen_isa_register (const char **strp) +{ + int len; + int ch1, ch2; + + if (**strp == 'r' || **strp == 'R') + { + len = strlen (*strp); + if (len == 2) + { + ch1 = (*strp)[1]; + if ('0' <= ch1 && ch1 <= '9') + return 1; + } + else if (len == 3) + { + ch1 = (*strp)[1]; + ch2 = (*strp)[2]; + if (('1' <= ch1 && ch1 <= '2') && ('0' <= ch2 && ch2 <= '9')) + return 1; + if ('3' == ch1 && (ch2 == '0' || ch2 == '1')) + return 1; + } + } + if (**strp == '%' + && TOLOWER ((*strp)[1]) != 'l' + && TOLOWER ((*strp)[1]) != 'h') + return 1; + return 0; +} + +/* Handle negated literal. */ + +static const char * +parse_mimm (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg; + + /* Verify this isn't a register. */ + if (iq2000_cgen_isa_register (strp)) + errmsg = _("immediate value cannot be register"); + else + { + long value; + + errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); + if (errmsg == NULL) + { + long x = (-value) & 0xFFFF0000; + + if (x != 0 && x != (long) 0xFFFF0000) + errmsg = _("immediate value out of range"); + else + *valuep = (-value & 0xFFFF); + } + } + return errmsg; +} + +/* Handle signed/unsigned literal. */ + +static const char * +parse_imm (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg; + + if (iq2000_cgen_isa_register (strp)) + errmsg = _("immediate value cannot be register"); + else + { + long value; + + errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); + if (errmsg == NULL) + { + long x = value & 0xFFFF0000; + + if (x != 0 && x != (long) 0xFFFF0000) + errmsg = _("immediate value out of range"); + else + *valuep = (value & 0xFFFF); + } + } + return errmsg; +} + +/* Handle iq10 21-bit jmp offset. */ + +static const char * +parse_jtargq10 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + int reloc ATTRIBUTE_UNUSED, + enum cgen_parse_operand_result *type_addr ATTRIBUTE_UNUSED, + bfd_vma *valuep) +{ + const char *errmsg; + bfd_vma value; + enum cgen_parse_operand_result result_type = CGEN_PARSE_OPERAND_RESULT_NUMBER; + + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IQ2000_OFFSET_21, + & result_type, & value); + if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + { + /* Check value is within 23-bits + (remembering that 2-bit shift right will occur). */ + if (value > 0x7fffff) + return _("21-bit offset out of range"); + } + *valuep = (value & 0x7FFFFF); + return errmsg; +} + +/* Handle high(). */ + +static const char * +parse_hi16 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + if (strncasecmp (*strp, "%hi(", 4) == 0) + { + enum cgen_parse_operand_result result_type; + bfd_vma value; + const char *errmsg; + + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + { + /* If value has top-bit of %lo on, then it will + sign-propagate and so we compensate by adding + 1 to the resultant %hi value. */ + if (value & 0x8000) + value += 0x10000; + value >>= 16; + value &= 0xffff; + } + *valuep = value; + + return errmsg; + } + + /* We add %uhi in case a user just wants the high 16-bits or is using + an insn like ori for %lo which does not sign-propagate. */ + if (strncasecmp (*strp, "%uhi(", 5) == 0) + { + enum cgen_parse_operand_result result_type; + bfd_vma value; + const char *errmsg; + + *strp += 5; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IQ2000_UHI16, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value >>= 16; + + value &= 0xffff; + *valuep = value; + + return errmsg; + } + + return parse_imm (cd, strp, opindex, valuep); +} + +/* Handle %lo in a signed context. + The signedness of the value doesn't matter to %lo(), but this also + handles the case where %lo() isn't present. */ + +static const char * +parse_lo16 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + if (strncasecmp (*strp, "%lo(", 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_LO16, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*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 %lo in a negated signed context. + The signedness of the value doesn't matter to %lo(), but this also + handles the case where %lo() isn't present. */ + +static const char * +parse_mlo16 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + if (strncasecmp (*strp, "%lo(", 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_LO16, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (-value) & 0xffff; + *valuep = value; + return errmsg; + } + + return parse_mimm (cd, strp, opindex, valuep); +} + +/* -- */ diff --git a/cpu/iq2000m.cpu b/cpu/iq2000m.cpu new file mode 100644 index 00000000000..59422415537 --- /dev/null +++ b/cpu/iq2000m.cpu @@ -0,0 +1,631 @@ +; IQ2000-only CPU description. -*- Scheme -*- +; +; Copyright 2000, 2001, 2002, 2004, 2007, 2009 Free Software Foundation, Inc. +; +; Contributed by Red Hat Inc; developed under contract from Vitesse. +; +; 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. + +(dni andoui "and upper ones immediate" (MACH2000 USES-RS USES-RT) + "andoui $rt,$rs,$hi16" + (+ OP_ANDOUI rs rt hi16) + (set rt (and rs (or (sll hi16 16) #xFFFF))) + ()) + +(dni andoui2 "and upper ones immediate" (ALIAS NO-DIS MACH2000 USES-RS USES-RT) + "andoui ${rt-rs},$hi16" + (+ OP_ANDOUI rt-rs hi16) + (set rt-rs (and rt-rs (or (sll hi16 16) #xFFFF))) + ()) + +(dni orui2 "or upper immediate" (ALIAS NO-DIS MACH2000 USES-RS USES-RT) + "orui ${rt-rs},$hi16" + (+ OP_ORUI rt-rs hi16) + (set rt-rs (or rt-rs (sll hi16 16))) + ()) + +(dni orui "or upper immediate" (MACH2000 USES-RS USES-RT) + "orui $rt,$rs,$hi16" + (+ OP_ORUI rs rt hi16) + (set rt (or rs (sll hi16 16))) + ()) + +(dni bgtz "branch if greater than zero" (MACH2000 USES-RS) + "bgtz $rs,$offset" + (+ OP_BGTZ rs (f-rt 0) offset) + (if (gt rs 0) + (delay 1 (set pc offset))) + ()) + + +(dni bgtzl "branch if greater than zero likely" (MACH2000 USES-RS) + "bgtzl $rs,$offset" + (+ OP_BGTZL rs (f-rt 0) offset) + (if (gt rs 0) + (delay 1 (set pc offset)) + (skip 1)) + ()) + +(dni blez "branch if less than or equal to zero" (MACH2000 USES-RS) + "blez $rs,$offset" + (+ OP_BLEZ rs (f-rt 0) offset) + (if (le rs 0) + (delay 1 (set pc offset))) + ()) + +(dni blezl "branch if less than or equal to zero likely" (MACH2000 USES-RS) + "blezl $rs,$offset" + (+ OP_BLEZL rs (f-rt 0) offset) + (if (le rs 0) + (delay 1 (set pc offset)) + (skip 1)) + ()) + + +(dni mrgb "merge bytes" (MACH2000 USES-RD USES-RS USES-RT) + "mrgb $rd,$rs,$rt,$mask" + (+ OP_SPECIAL rs rt rd (f-10 0) mask FUNC_MRGB) + (sequence ((SI temp)) + (if (bitclear? mask 0) + (set temp (and rs #xFF)) + (set temp (and rt #xFF))) + (if (bitclear? mask 1) + (set temp (or temp (and rs #xFF00))) + (set temp (or temp (and rt #xFF00)))) + (if (bitclear? mask 2) + (set temp (or temp (and rs #xFF0000))) + (set temp (or temp (and rt #xFF0000)))) + (if (bitclear? mask 3) + (set temp (or temp (and rs #xFF000000))) + (set temp (or temp (and rt #xFF000000)))) + (set rd temp)) + ()) + +(dni mrgb2 "merge bytes" (ALIAS NO-DIS MACH2000 USES-RD USES-RS USES-RT) + "mrgb ${rd-rs},$rt,$mask" + (+ OP_SPECIAL rt rd-rs (f-10 0) mask FUNC_MRGB) + (sequence ((SI temp)) + (if (bitclear? mask 0) + (set temp (and rd-rs #xFF)) + (set temp (and rt #xFF))) + (if (bitclear? mask 1) + (set temp (or temp (and rd-rs #xFF00))) + (set temp (or temp (and rt #xFF00)))) + (if (bitclear? mask 2) + (set temp (or temp (and rd-rs #xFF0000))) + (set temp (or temp (and rt #xFF0000)))) + (if (bitclear? mask 3) + (set temp (or temp (and rd-rs #xFF000000))) + (set temp (or temp (and rt #xFF000000)))) + (set rd-rs temp)) + ()) + +; NOTE: None of these instructions' semantics are specified, so they +; will not work in a simulator. +; +; Architectural and coprocessor instructions. +; BREAK and SYSCALL are implemented with escape hatches to the C +; code. These are used by the test suite to indicate pass/failures. + +(dni bctxt "branch and switch context" (MACH2000 DELAY-SLOT COND-CTI USES-RS) + "bctxt $rs,$offset" + (+ OP_REGIMM rs (f-rt 6) offset) + (unimp bctxt) + ()) + +(dni bc0f "branch if copro 0 condition false" (MACH2000 DELAY-SLOT COND-CTI) + "bc0f $offset" + (+ OP_COP0 (f-rs 8) (f-rt 0) offset) + (unimp bc0f) + ()) + +(dni bc0fl "branch if copro 0 condition false likely" (MACH2000 DELAY-SLOT COND-CTI SKIP-CTI) + "bc0fl $offset" + (+ OP_COP0 (f-rs 8) (f-rt 2) offset) + (unimp bc0fl) + ()) + +(dni bc3f "branch if copro 3 condition false" (MACH2000 DELAY-SLOT COND-CTI) + "bc3f $offset" + (+ OP_COP3 (f-rs 8) (f-rt 0) offset) + (unimp bc3f) + ()) + +(dni bc3fl "branch if copro 3 condition false likely" (MACH2000 DELAY-SLOT COND-CTI SKIP-CTI) + "bc3fl $offset" + (+ OP_COP3 (f-rs 8) (f-rt 2) offset) + (unimp bc3fl) + ()) + +(dni bc0t "branch if copro 0 condition true" (MACH2000 DELAY-SLOT COND-CTI) + "bc0t $offset" + (+ OP_COP0 (f-rs 8) (f-rt 1) offset) + (unimp bc0t) + ()) + +(dni bc0tl "branch if copro 0 condition true likely" (MACH2000 DELAY-SLOT COND-CTI SKIP-CTI) + "bc0tl $offset" + (+ OP_COP0 (f-rs 8) (f-rt 3) offset) + (unimp bc0tl) + ()) + +(dni bc3t "branch if copro 3 condition true" (MACH2000 DELAY-SLOT COND-CTI) + "bc3t $offset" + (+ OP_COP3 (f-rs 8) (f-rt 1) offset) + (unimp bc3t) + ()) + +(dni bc3tl "branch if copro 3 condition true likely" (MACH2000 DELAY-SLOT COND-CTI SKIP-CTI) + "bc3tl $offset" + (+ OP_COP3 (f-rs 8) (f-rt 3) offset) + (unimp bc3tl) + ()) + +; Note that we don't set the USES-RD or USES-RT attributes for many of the following +; instructions, as it's the COP register that's being specified. + +(dni cfc0 "control from coprocessor 0" (MACH2000 LOAD-DELAY USES-RT) + "cfc0 $rt,$rd" + (+ OP_COP0 (f-rs 2) rt rd (f-10-11 0)) + (unimp cfc0) + ()) + +(dni cfc1 "control from coprocessor 1" (MACH2000 LOAD-DELAY USES-RT) + "cfc1 $rt,$rd" + (+ OP_COP1 (f-rs 2) rt rd (f-10-11 0)) + (unimp cfc1) + ()) + +(dni cfc2 "control from coprocessor 2" (MACH2000 LOAD-DELAY USES-RT YIELD-INSN) + "cfc2 $rt,$rd" + (+ OP_COP2 (f-rs 2) rt rd (f-10-11 0)) + (unimp cfc2) + ()) + +(dni cfc3 "control from coprocessor 3" (MACH2000 LOAD-DELAY USES-RT YIELD-INSN) + "cfc3 $rt,$rd" + (+ OP_COP3 (f-rs 2) rt rd (f-10-11 0)) + (unimp cfc3) + ()) + +; COPz instructions are an instruction form, not real instructions +; with associated assembly mnemonics. Therefore, they are omitted +; from the ISA description. + +(dni chkhdr "check header" (MACH2000 LOAD-DELAY USES-RD YIELD-INSN) + "chkhdr $rd,$rt" + (+ OP_COP3 (f-rs 9) rt rd (f-shamt 0) (f-func 0)) + (unimp chkhdr) + ()) + +(dni ctc0 "control to coprocessor 0" (MACH2000 USES-RT) + "ctc0 $rt,$rd" + (+ OP_COP0 (f-rs 6) rt rd (f-10-11 0)) + (unimp ctc0) + ()) + +(dni ctc1 "control to coprocessor 1" (MACH2000 USES-RT) + "ctc1 $rt,$rd" + (+ OP_COP1 (f-rs 6) rt rd (f-10-11 0)) + (unimp ctc1) + ()) + +(dni ctc2 "control to coprocessor 2" (MACH2000 USES-RT) + "ctc2 $rt,$rd" + (+ OP_COP2 (f-rs 6) rt rd (f-10-11 0)) + (unimp ctc2) + ()) + +(dni ctc3 "control to coprocessor 3" (MACH2000 USES-RT) + "ctc3 $rt,$rd" + (+ OP_COP3 (f-rs 6) rt rd (f-10-11 0)) + (unimp ctc3) + ()) + +(dni jcr "jump context register" (MACH2000 DELAY-SLOT UNCOND-CTI USES-RS) + "jcr $rs" + (+ OP_SPECIAL rs (f-rt 0) (f-rd 0) (f-shamt 0) FUNC_JCR) + (unimp jcr) + ()) + +(dni luc32 "lookup chain 32 bits" (MACH2000 USES-RD USES-RT YIELD-INSN) + "luc32 $rt,$rd" + (+ OP_COP2 (f-rs 1) rt rd (f-shamt 0) (f-func 3)) + (unimp luc32) + ()) + +(dni luc32l "lookup chain 32 bits and lock" (MACH2000 USES-RD USES-RT YIELD-INSN) + "luc32l $rt,$rd" + (+ OP_COP2 (f-rs 1) rt rd (f-shamt 0) (f-func 7)) + (unimp luc32l) + ()) + +(dni luc64 "lookup chain 64 bits" (MACH2000 USES-RD USES-RT YIELD-INSN) + "luc64 $rt,$rd" + (+ OP_COP2 (f-rs 1) rt rd (f-shamt 0) (f-func 11)) + (unimp luc64) + ()) + +(dni luc64l "lookup chain 64 bits and lock" (MACH2000 USES-RD USES-RT YIELD-INSN) + "luc64l $rt,$rd" + (+ OP_COP2 (f-rs 1) rt rd (f-shamt 0) (f-func 15)) + (unimp luc64l) + ()) + +(dni luk "lookup key" (MACH2000 USES-RD USES-RT) + "luk $rt,$rd" + (+ OP_COP2 (f-rs 1) rt rd (f-shamt 0) (f-func 8)) + (unimp luk) + ()) + +(dni lulck "lookup lock" (MACH2000 USES-RT YIELD-INSN) + "lulck $rt" + (+ OP_COP2 (f-rs 1) rt (f-rd 0) (f-shamt 0) (f-func 4)) + (unimp lulck) + ()) + +(dni lum32 "lookup match 32 bits" (MACH2000 USES-RD USES-RT YIELD-INSN) + "lum32 $rt,$rd" + (+ OP_COP2 (f-rs 1) rt rd (f-shamt 0) (f-func 2)) + (unimp lum32) + ()) + +(dni lum32l "lookup match 32 bits and lock" (MACH2000 USES-RD USES-RT YIELD-INSN) + "lum32l $rt,$rd" + (+ OP_COP2 (f-rs 1) rt rd (f-shamt 0) (f-func 6)) + (unimp lum32l) + ()) + +(dni lum64 "lookup match 64 bits" (MACH2000 USES-RD USES-RT YIELD-INSN) + "lum64 $rt,$rd" + (+ OP_COP2 (f-rs 1) rt rd (f-shamt 0) (f-func 10)) + (unimp lum64) + ()) + +(dni lum64l "lookup match 64 bits and lock" (MACH2000 USES-RD USES-RT YIELD-INSN) + "lum64l $rt,$rd" + (+ OP_COP2 (f-rs 1) rt rd (f-shamt 0) (f-func 14)) + (unimp lum64l) + ()) + +(dni lur "lookup read" (MACH2000 USES-RD USES-RT YIELD-INSN) + "lur $rt,$rd" + (+ OP_COP2 (f-rs 1) rt rd (f-shamt 0) (f-func 1)) + (unimp lur) + ()) + +(dni lurl "lookup read and lock" (MACH2000 USES-RD USES-RT YIELD-INSN) + "lurl $rt,$rd" + (+ OP_COP2 (f-rs 1) rt rd (f-shamt 0) (f-func 5)) + (unimp lurl) + ()) + +(dni luulck "lookup unlock" (MACH2000 USES-RT YIELD-INSN) + "luulck $rt" + (+ OP_COP2 (f-rs 1) rt (f-rd 0) (f-shamt 0) (f-func 0)) + (unimp luulck) + ()) + +(dni mfc0 "move from coprocessor 0" (MACH2000 LOAD-DELAY USES-RT) + "mfc0 $rt,$rd" + (+ OP_COP0 (f-rs 0) rt rd (f-10-11 0)) + (unimp mfc0) + ()) + +(dni mfc1 "move from coprocessor 1" (MACH2000 LOAD-DELAY USES-RT) + "mfc1 $rt,$rd" + (+ OP_COP1 (f-rs 0) rt rd (f-10-11 0)) + (unimp mfc1) + ()) + +(dni mfc2 "move from coprocessor 2" (MACH2000 LOAD-DELAY USES-RT YIELD-INSN) + "mfc2 $rt,$rd" + (+ OP_COP2 (f-rs 0) rt rd (f-10-11 0)) + (unimp mfc2) + ()) + +(dni mfc3 "move from coprocessor 3" (MACH2000 LOAD-DELAY USES-RT YIELD-INSN) + "mfc3 $rt,$rd" + (+ OP_COP3 (f-rs 0) rt rd (f-10-11 0)) + (unimp mfc3) + ()) + +(dni mtc0 "move to coprocessor 0" (MACH2000 USES-RT) + "mtc0 $rt,$rd" + (+ OP_COP0 (f-rs 4) rt rd (f-10-11 0)) + (unimp mtc0) + ()) + +(dni mtc1 "move to coprocessor 1" (MACH2000 USES-RT) + "mtc1 $rt,$rd" + (+ OP_COP1 (f-rs 4) rt rd (f-10-11 0)) + (unimp mtc1) + ()) + +(dni mtc2 "move to coprocessor 2" (MACH2000 USES-RT) + "mtc2 $rt,$rd" + (+ OP_COP2 (f-rs 4) rt rd (f-10-11 0)) + (unimp mtc2) + ()) + +(dni mtc3 "move to coprocessor 3" (MACH2000 USES-RT) + "mtc3 $rt,$rd" + (+ OP_COP3 (f-rs 4) rt rd (f-10-11 0)) + (unimp mtc3) + ()) + +(dni pkrl "pkrl" (MACH2000 USES-RD USES-RT YIELD-INSN) + "pkrl $rd,$rt" + (+ OP_COP3 (f-rs 1) rt rd (f-shamt 0) (f-func 7)) + (unimp pkrl) + ()) + +(dni pkrlr1 "pkrlr1" (MACH2000 USES-RT YIELD-INSN) + "pkrlr1 $rt,$_index,$count" + (+ OP_COP3 (f-rs 29) rt count _index) + (unimp pkrlr1) + ()) + +(dni pkrlr30 "pkrlr30" (MACH2000 USES-RT YIELD-INSN) + "pkrlr30 $rt,$_index,$count" + (+ OP_COP3 (f-rs 31) rt count _index) + (unimp pkrlr30) + ()) + +(dni rb "dma read bytes" (MACH2000 USES-RD USES-RT YIELD-INSN) + "rb $rd,$rt" + (+ OP_COP3 (f-rs 1) rt rd (f-shamt 0) (f-func 4)) + (unimp rb) + ()) + +(dni rbr1 "dma read bytes using r1" (MACH2000 USES-RT YIELD-INSN) + "rbr1 $rt,$_index,$count" + (+ OP_COP3 (f-rs 24) rt count _index) + (unimp rbr1) + ()) + +(dni rbr30 "dma read bytes using r30" (MACH2000 USES-RT YIELD-INSN) + "rbr30 $rt,$_index,$count" + (+ OP_COP3 (f-rs 26) rt count _index) + (unimp rbr30) + ()) + +(dni rfe "restore from exception" (MACH2000) + "rfe" + (+ OP_COP0 (f-25 1) (f-24-19 0) (f-func 16)) + (unimp rfe) + ()) + +(dni rx "dma read word64s" (MACH2000 USES-RD USES-RT YIELD-INSN) + "rx $rd,$rt" + (+ OP_COP3 (f-rs 1) rt rd (f-shamt 0) (f-func 6)) + (unimp rx) + ()) + +(dni rxr1 "dma read word64s using r1" (MACH2000 USES-RT YIELD-INSN) + "rxr1 $rt,$_index,$count" + (+ OP_COP3 (f-rs 28) rt count _index) + (unimp rxr1) + ()) + +(dni rxr30 "dma read word 64s using r30" (MACH2000 USES-RT YIELD-INSN) + "rxr30 $rt,$_index,$count" + (+ OP_COP3 (f-rs 30) rt count _index) + (unimp rxr30) + ()) + +(dni sleep "sleep" (MACH2000 YIELD-INSN) + "sleep" + (+ OP_SPECIAL execode FUNC_SLEEP) + (unimp sleep) + ()) + +(dni srrd "sram read" (MACH2000 USES-RT YIELD-INSN) + "srrd $rt" + (+ OP_COP2 (f-rs 1) rt (f-rd 0) (f-shamt 0) (f-func 16)) + (unimp srrd) + ()) + +(dni srrdl "sram read and lock" (MACH2000 USES-RT YIELD-INSN) + "srrdl $rt" + (+ OP_COP2 (f-rs 1) rt (f-rd 0) (f-shamt 0) (f-func 20)) + (unimp srrdl) + ()) + +(dni srulck "sram unlock" (MACH2000 USES-RT YIELD-INSN) + "srulck $rt" + (+ OP_COP2 (f-rs 1) rt (f-rd 0) (f-shamt 0) (f-func 22)) + (unimp srulck) + ()) + +(dni srwr "sram write" (MACH2000 USES-RD USES-RT YIELD-INSN) + "srwr $rt,$rd" + (+ OP_COP2 (f-rs 1) rt rd (f-shamt 0) (f-func 17)) + (unimp srwr) + ()) + +(dni srwru "sram write and unlock" (MACH2000 USES-RD USES-RT YIELD-INSN) + "srwru $rt,$rd" + (+ OP_COP2 (f-rs 1) rt rd (f-shamt 0) (f-func 21)) + (unimp srwru) + ()) + +(dni trapqfl "yield if dma queue full" (MACH2000 YIELD-INSN) + "trapqfl" + (+ OP_COP3 (f-rs 1) (f-rt 0) (f-rd 0) (f-shamt 0) (f-func 8)) + (unimp trapqfl) + ()) + +(dni trapqne "yield if dma queue not empty" (MACH2000 YIELD-INSN) + "trapqne" + (+ OP_COP3 (f-rs 1) (f-rt 0) (f-rd 0) (f-shamt 0) (f-func 9)) + (unimp trapqne) + ()) + +(dni traprel "traprel" (MACH2000 USES-RT YIELD-INSN) + "traprel $rt" + (+ OP_COP3 (f-rs 1) rt (f-rd 0) (f-shamt 0) (f-func 10)) + (unimp traprel) + ()) + +(dni wb "dma write bytes" (MACH2000 USES-RD USES-RT YIELD-INSN) + "wb $rd,$rt" + (+ OP_COP3 (f-rs 1) rt rd (f-shamt 0) (f-func 0)) + (unimp wb) + ()) + +(dni wbu "dma write bytes and unlock" (MACH2000 USES-RD USES-RT YIELD-INSN) + "wbu $rd,$rt" + (+ OP_COP3 (f-rs 1) rt rd (f-shamt 0) (f-func 1)) + (unimp wbu) + ()) + +(dni wbr1 "dma write bytes using r1" (MACH2000 USES-RT YIELD-INSN) + "wbr1 $rt,$_index,$count" + (+ OP_COP3 (f-rs 16) rt count _index) + (unimp wbr1) + ()) + +(dni wbr1u "dma write bytes using r1 and unlock" (MACH2000 USES-RT YIELD-INSN) + "wbr1u $rt,$_index,$count" + (+ OP_COP3 (f-rs 17) rt count _index) + (unimp wbr1u) + ()) + +(dni wbr30 "dma write bytes using r30" (MACH2000 USES-RT YIELD-INSN) + "wbr30 $rt,$_index,$count" + (+ OP_COP3 (f-rs 18) rt count _index) + (unimp wbr30) + ()) + +(dni wbr30u "dma write bytes using r30 and unlock" (MACH2000 USES-RT YIELD-INSN) + "wbr30u $rt,$_index,$count" + (+ OP_COP3 (f-rs 19) rt count _index) + (unimp wbr30u) + ()) + +(dni wx "dma write word64s" (MACH2000 USES-RD USES-RT YIELD-INSN) + "wx $rd,$rt" + (+ OP_COP3 (f-rs 1) rt rd (f-shamt 0) (f-func 2)) + (unimp wx) + ()) + +(dni wxu "dma write word64s and unlock" (MACH2000 USES-RD USES-RT YIELD-INSN) + "wxu $rd,$rt" + (+ OP_COP3 (f-rs 1) rt rd (f-shamt 0) (f-func 3)) + (unimp wxu) + ()) + +(dni wxr1 "dma write word64s using r1" (MACH2000 USES-RT YIELD-INSN) + "wxr1 $rt,$_index,$count" + (+ OP_COP3 (f-rs 20) rt count _index) + (unimp wxr1) + ()) + +(dni wxr1u "dma write word64s using r1 and unlock" (MACH2000 USES-RT YIELD-INSN) + "wxr1u $rt,$_index,$count" + (+ OP_COP3 (f-rs 21) rt count _index) + (unimp wxr1u) + ()) + +(dni wxr30 "dma write word64s using r30" (MACH2000 USES-RT YIELD-INSN) + "wxr30 $rt,$_index,$count" + (+ OP_COP3 (f-rs 22) rt count _index) + (unimp wxr30) + ()) + +(dni wxr30u "dma write word64s using r30 and unlock" (MACH2000 USES-RT YIELD-INSN) + "wxr30u $rt,$_index,$count" + (+ OP_COP3 (f-rs 23) rt count _index) + (unimp wxr30u) + ()) + + +; Load/Store instructions. + +(dni ldw "load double word" (MACH2000 EVEN-REG-NUM LOAD-DELAY USES-RT) + "ldw $rt,$lo16($base)" + (+ OP_LDW base rt lo16) + (sequence ((SI addr)) + (set addr (and (add base lo16) (inv 3))) + (set (reg h-gr (add (ifield f-rt) 1)) (mem SI addr)) + (set rt (mem SI (add addr 4)))) + ()) + +(dni sdw "store double word" (MACH2000 EVEN-REG-NUM USES-RT) + "sdw $rt,$lo16($base)" + (+ OP_SDW base rt lo16) + (sequence ((SI addr)) + (set addr (and (add base lo16) (inv 3))) + (set (mem SI (add addr 4)) rt) + (set (mem SI addr) (reg h-gr (add (ifield f-rt) 1)))) + ()) + + +; Jump instructions + +(dni j "jump" (MACH2000) + "j $jmptarg" + (+ OP_J (f-rsrvd 0) jmptarg) + (delay 1 (set pc jmptarg)) + ()) + +(dni jal "jump and link" (MACH2000 USES-R31) + "jal $jmptarg" + (+ OP_JAL (f-rsrvd 0) jmptarg) + (delay 1 + (sequence () + (set (reg h-gr 31) (add pc 8)) + (set pc jmptarg))) + ()) + +(dni bmb "branch if matching byte-lane" (MACH2000 USES-RS USES-RT) + "bmb $rs,$rt,$offset" + (+ OP_BMB rs rt offset) + (sequence ((BI branch?)) + (set branch? 0) + (if (eq (and rs #xFF) (and rt #xFF)) + (set branch? 1)) + (if (eq (and rs #xFF00) (and rt #xFF00)) + (set branch? 1)) + (if (eq (and rs #xFF0000) (and rt #xFF0000)) + (set branch? 1)) + (if (eq (and rs #xFF000000) (and rt #xFF000000)) + (set branch? 1)) + (if branch? + (delay 1 (set pc offset)))) + ()) + + +; Macros + +(dnmi ldw-base-0 "load double word - implied base 0" (MACH2000 EVEN-REG-NUM LOAD-DELAY USES-RT USES-RS NO-DIS) + "ldw $rt,$lo16" + (emit ldw rt lo16 (base 0)) +) + +(dnmi sdw-base-0 "store double word - implied base 0" (MACH2000 EVEN-REG-NUM USES-RT NO-DIS) + "sdw $rt,$lo16" + (emit sdw rt lo16 (base 0)) +) + + + + + + diff --git a/cpu/lm32.cpu b/cpu/lm32.cpu new file mode 100644 index 00000000000..31b943d79eb --- /dev/null +++ b/cpu/lm32.cpu @@ -0,0 +1,932 @@ +; Lattice Mico32 CPU description. -*- Scheme -*- +; Copyright 2008, 2009 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 00000000000..3a814c2e03c --- /dev/null +++ b/cpu/lm32.opc @@ -0,0 +1,235 @@ +/* Lattice Mico32 opcode support. -*- C -*- + Copyright 2008, 2009 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)"); +} diff --git a/cpu/m32c.cpu b/cpu/m32c.cpu new file mode 100644 index 00000000000..127da499ef2 --- /dev/null +++ b/cpu/m32c.cpu @@ -0,0 +1,10520 @@ +; Renesas M32C CPU description. -*- Scheme -*- +; +; Copyright 2005, 2006, 2007, 2009 Free Software Foundation, Inc. +; +; Contributed by Red Hat Inc; developed under contract from Renesas. +; +; 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 m32c) + (comment "Renesas M32C") + (default-alignment forced) + (insn-lsb0? #f) + (machs m16c m32c) + (isas m16c m32c) +) + +(define-isa + (name m16c) + + (default-insn-bitsize 32) + + ; Number of bytes of insn we can initially fetch. + (base-insn-bitsize 32) + + ; Used in computing bit numbers. + (default-insn-word-bitsize 32) + + (decode-assist (0 1 2 3 4 5 6 7)) ; Initial bitnumbers to decode insns by. + + ; fetches 1 insn at a time. + (liw-insns 1) + + ; executes 1 insn at a time. + (parallel-insns 1) + ) + +(define-isa + (name m32c) + + (default-insn-bitsize 32) + + ; Number of bytes of insn we can initially fetch. + (base-insn-bitsize 32) + + ; Used in computing bit numbers. + (default-insn-word-bitsize 32) + + (decode-assist (0 1 2 3 4 5 6 7)) ; Initial bitnumbers to decode insns by. + + ; fetches 1 insn at a time. + (liw-insns 1) + + ; executes 1 insn at a time. + (parallel-insns 1) + ) + +(define-cpu + ; cpu names must be distinct from the architecture name and machine names. + ; The "b" suffix stands for "base" and is the convention. + ; The "f" suffix stands for "family" and is the convention. + (name m16cbf) + (comment "Renesas M16C base family") + (insn-endian big) + (data-endian little) + (word-bitsize 16) +) + +(define-cpu + ; cpu names must be distinct from the architecture name and machine names. + ; The "b" suffix stands for "base" and is the convention. + ; The "f" suffix stands for "family" and is the convention. + (name m32cbf) + (comment "Renesas M32C base family") + (insn-endian big) + (data-endian little) + (word-bitsize 16) +) + +(define-mach + (name m16c) + (comment "Generic M16C cpu") + (cpu m32cbf) +) + +(define-mach + (name m32c) + (comment "Generic M32C cpu") + (cpu m32cbf) +) + +; Model descriptions. + +(define-model + (name m16c) + (comment "m16c") (attrs) + (mach m16c) + + ; `state' is a list of variables for recording model state + ; (state) + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) +) + +(define-model + (name m32c) + (comment "m32c") (attrs) + (mach m32c) + + ; `state' is a list of variables for recording model state + ; (state) + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) +) + +(define-attr + (type enum) + (name RL_TYPE) + (values NONE JUMP 1ADDR 2ADDR) + (default NONE) + ) + +; Macros to simplify MACH attribute specification. + +(define-pmacro all-isas () (ISA m16c,m32c)) +(define-pmacro m16c-isa () (ISA m16c)) +(define-pmacro m32c-isa () (ISA m32c)) + +(define-pmacro MACH16 (MACH m16c)) +(define-pmacro MACH32 (MACH m32c)) + +(define-pmacro (machine size) + (MACH (.sym m size c)) (ISA (.sym m size c))) + +(define-pmacro RL_JUMP (RL_TYPE JUMP)) +(define-pmacro RL_1ADDR (RL_TYPE 1ADDR)) +(define-pmacro RL_2ADDR (RL_TYPE 2ADDR)) + + +;============================================================= +; Fields +;------------------------------------------------------------- +; Main opcodes +; +(dnf f-0-1 "opcode" (all-isas) 0 1) +(dnf f-0-2 "opcode" (all-isas) 0 2) +(dnf f-0-3 "opcode" (all-isas) 0 3) +(dnf f-0-4 "opcode" (all-isas) 0 4) +(dnf f-1-3 "opcode" (all-isas) 1 3) +(dnf f-2-2 "opcode" (all-isas) 2 2) +(dnf f-3-4 "opcode" (all-isas) 3 4) +(dnf f-3-1 "opcode" (all-isas) 3 1) +(dnf f-4-1 "opcode" (all-isas) 4 1) +(dnf f-4-3 "opcode" (all-isas) 4 3) +(dnf f-4-4 "opcode" (all-isas) 4 4) +(dnf f-4-6 "opcode" (all-isas) 4 6) +(dnf f-5-1 "opcode" (all-isas) 5 1) +(dnf f-5-3 "opcode" (all-isas) 5 3) +(dnf f-6-2 "opcode" (all-isas) 6 2) +(dnf f-7-1 "opcode" (all-isas) 7 1) +(dnf f-8-1 "opcode" (all-isas) 8 1) +(dnf f-8-2 "opcode" (all-isas) 8 2) +(dnf f-8-3 "opcode" (all-isas) 8 3) +(dnf f-8-4 "opcode" (all-isas) 8 4) +(dnf f-8-8 "opcode" (all-isas) 8 8) +(dnf f-9-3 "opcode" (all-isas) 9 3) +(dnf f-9-1 "opcode" (all-isas) 9 1) +(dnf f-10-1 "opcode" (all-isas) 10 1) +(dnf f-10-2 "opcode" (all-isas) 10 2) +(dnf f-10-3 "opcode" (all-isas) 10 3) +(dnf f-11-1 "opcode" (all-isas) 11 1) +(dnf f-12-1 "opcode" (all-isas) 12 1) +(dnf f-12-2 "opcode" (all-isas) 12 2) +(dnf f-12-3 "opcode" (all-isas) 12 3) +(dnf f-12-4 "opcode" (all-isas) 12 4) +(dnf f-12-6 "opcode" (all-isas) 12 6) +(dnf f-13-3 "opcode" (all-isas) 13 3) +(dnf f-14-1 "opcode" (all-isas) 14 1) +(dnf f-14-2 "opcode" (all-isas) 14 2) +(dnf f-15-1 "opcode" (all-isas) 15 1) +(dnf f-16-1 "opcode" (all-isas) 16 1) +(dnf f-16-2 "opcode" (all-isas) 16 2) +(dnf f-16-4 "opcode" (all-isas) 16 4) +(dnf f-16-8 "opcode" (all-isas) 16 8) +(dnf f-18-1 "opcode" (all-isas) 18 1) +(dnf f-18-2 "opcode" (all-isas) 18 2) +(dnf f-18-3 "opcode" (all-isas) 18 3) +(dnf f-20-1 "opcode" (all-isas) 20 1) +(dnf f-20-3 "opcode" (all-isas) 20 3) +(dnf f-20-2 "opcode" (all-isas) 20 2) +(dnf f-20-4 "opcode" (all-isas) 20 4) +(dnf f-21-3 "opcode" (all-isas) 21 3) +(dnf f-24-2 "opcode" (all-isas) 24 2) +(dnf f-24-8 "opcode" (all-isas) 24 8) +(dnf f-32-16 "opcode" (all-isas) 32 16) + +;------------------------------------------------------------- +; Registers +;------------------------------------------------------------- + +(dnf f-src16-rn "source Rn for m16c" (MACH16 m16c-isa) 10 2) +(dnf f-src16-an "source An for m16c" (MACH16 m16c-isa) 11 1) + +(dnf f-src32-an-unprefixed "destination An for m32c" (MACH32 m32c-isa) 11 1) +(dnf f-src32-an-prefixed "destination An for m32c" (MACH32 m32c-isa) 19 1) + +; QI mode gr encoding for m32c is different than for m16c. The hardware +; is indexed using the m16c encoding, so perform the transformation here. +; register m16c m32c +; ---------------------- +; r0l 00'b 10'b +; r0h 01'b 00'b +; r1l 10'b 11'b +; r1h 11'b 01'b +(df f-src32-rn-unprefixed-QI "source Rn QI for m32c" (MACH32 m32c-isa) 10 2 UINT + ((value pc) (or USI (and (sll (inv value) 1) 2) (and (srl value 1) 1))) ; insert + ((value pc) (or USI (and (inv (srl value 1)) 1) (and (sll value 1) 2))) ; extract +) +; QI mode gr encoding for m32c is different than for m16c. The hardware +; is indexed using the m16c encoding, so perform the transformation here. +; register m16c m32c +; ---------------------- +; r0l 00'b 10'b +; r0h 01'b 00'b +; r1l 10'b 11'b +; r1h 11'b 01'b +(df f-src32-rn-prefixed-QI "source Rn QI for m32c" (MACH32 m32c-isa) 18 2 UINT + ((value pc) (or USI (and (sll (inv value) 1) 2) (and (srl value 1) 1))) ; insert + ((value pc) (or USI (and (inv (srl value 1)) 1) (and (sll value 1) 2))) ; extract +) +; HI mode gr encoding for m32c is different than for m16c. The hardware +; is indexed using the m16c encoding, so perform the transformation here. +; register m16c m32c +; ---------------------- +; r0 00'b 10'b +; r1 01'b 11'b +; r2 10'b 00'b +; r3 11'b 01'b +(df f-src32-rn-unprefixed-HI "source Rn HI for m32c" (MACH32 m32c-isa) 10 2 UINT + ((value pc) (mod USI (add value 2) 4)) ; insert + ((value pc) (mod USI (add value 2) 4)) ; extract +) + +; HI mode gr encoding for m32c is different than for m16c. The hardware +; is indexed using the m16c encoding, so perform the transformation here. +; register m16c m32c +; ---------------------- +; r0 00'b 10'b +; r1 01'b 11'b +; r2 10'b 00'b +; r3 11'b 01'b +(df f-src32-rn-prefixed-HI "source Rn HI for m32c" (MACH32 m32c-isa) 18 2 UINT + ((value pc) (mod USI (add value 2) 4)) ; insert + ((value pc) (mod USI (add value 2) 4)) ; extract +) + +; SI mode gr encoding for m32c is as follows: +; register encoding index +; ------------------------- +; r2r0 10'b 0 +; r3r1 11'b 1 +(df f-src32-rn-unprefixed-SI "source Rn SI for m32c" (MACH32 m32c-isa) 10 2 UINT + ((value pc) (add USI value 2)) ; insert + ((value pc) (sub USI value 2)) ; extract +) +(df f-src32-rn-prefixed-SI "source Rn SI for m32c" (MACH32 m32c-isa) 18 2 UINT + ((value pc) (add USI value 2)) ; insert + ((value pc) (sub USI value 2)) ; extract +) + +(dnf f-dst32-rn-ext-unprefixed "destination Rn for m32c" (MACH32 m32c-isa) 9 1) + +(dnf f-dst16-rn "destination Rn for m16c" (MACH16 m16c-isa) 14 2) +(dnf f-dst16-rn-ext "destination Rn for m16c" (MACH16 m16c-isa) 14 1) +(dnf f-dst16-rn-QI-s "destination Rn for m16c" (MACH16 m16c-isa) 5 1) + +(dnf f-dst16-an "destination An for m16c" (MACH16 m16c-isa) 15 1) +(dnf f-dst16-an-s "destination An for m16c" (MACH16 m16c-isa) 4 1) + +(dnf f-dst32-an-unprefixed "destination An for m32c" (MACH32 m32c-isa) 9 1) +(dnf f-dst32-an-prefixed "destination An for m32c" (MACH32 m32c-isa) 17 1) + +; QI mode gr encoding for m32c is different than for m16c. The hardware +; is indexed using the m16c encoding, so perform the transformation here. +; register m16c m32c +; ---------------------- +; r0l 00'b 10'b +; r0h 01'b 00'b +; r1l 10'b 11'b +; r1h 11'b 01'b +(df f-dst32-rn-unprefixed-QI "destination Rn QI for m32c" (MACH32 m32c-isa) 8 2 UINT + ((value pc) (or USI (and (sll (inv value) 1) 2) (and (srl value 1) 1))) ; insert + ((value pc) (or USI (and (inv (srl value 1)) 1) (and (sll value 1) 2))) ; extract +) +(df f-dst32-rn-prefixed-QI "destination Rn QI for m32c" (MACH32 m32c-isa) 16 2 UINT + ((value pc) (or USI (and (sll (inv value) 1) 2) (and (srl value 1) 1))) ; insert + ((value pc) (or USI (and (inv (srl value 1)) 1) (and (sll value 1) 2))) ; extract +) +; HI mode gr encoding for m32c is different than for m16c. The hardware +; is indexed using the m16c encoding, so perform the transformation here. +; register m16c m32c +; ---------------------- +; r0 00'b 10'b +; r1 01'b 11'b +; r2 10'b 00'b +; r3 11'b 01'b +(df f-dst32-rn-unprefixed-HI "destination Rn HI for m32c" (MACH32 m32c-isa) 8 2 UINT + ((value pc) (mod USI (add value 2) 4)) ; insert + ((value pc) (mod USI (add value 2) 4)) ; extract +) +(df f-dst32-rn-prefixed-HI "destination Rn HI for m32c" (MACH32 m32c-isa) 16 2 UINT + ((value pc) (mod USI (add value 2) 4)) ; insert + ((value pc) (mod USI (add value 2) 4)) ; extract +) +; SI mode gr encoding for m32c is as follows: +; register encoding index +; ------------------------- +; r2r0 10'b 0 +; r3r1 11'b 1 +(df f-dst32-rn-unprefixed-SI "destination Rn SI for m32c" (MACH32 m32c-isa) 8 2 UINT + ((value pc) (add USI value 2)) ; insert + ((value pc) (sub USI value 2)) ; extract +) +(df f-dst32-rn-prefixed-SI "destination Rn SI for m32c" (MACH32 m32c-isa) 16 2 UINT + ((value pc) (add USI value 2)) ; insert + ((value pc) (sub USI value 2)) ; extract +) + +(dnf f-dst16-1-S "destination R0[hl] for m16c" (MACH16 m16c-isa) 5 1) + +;------------------------------------------------------------- +; Immediates embedded in the base insn +;------------------------------------------------------------- + +(df f-imm-8-s4 "4 bit signed" (all-isas) 8 4 INT #f #f) +(df f-imm-12-s4 "4 bit signed" (all-isas) 12 4 INT #f #f) +(df f-imm-13-u3 "3 bit unsigned" (all-isas) 13 3 UINT #f #f) +(df f-imm-20-s4 "4 bit signed" (all-isas) 20 4 INT #f #f) + +(df f-imm1-S "1 bit immediate for short format binary insns" (MACH32 m32c-isa) 2 1 UINT + ((value pc) (sub USI value 1)) ; insert + ((value pc) (add USI value 1)) ; extract +) + +(dnmf f-imm3-S "3 bit unsigned for short format insns" (all-isas) UINT + (f-2-2 f-7-1) + (sequence () ; insert + (set (ifield f-7-1) (and (sub (ifield f-imm3-S) 1) 1)) + (set (ifield f-2-2) (and (srl (sub (ifield f-imm3-S) 1) 1) #x3)) + ) + (sequence () ; extract + (set (ifield f-imm3-S) (add (or (sll (ifield f-2-2) 1) + (ifield f-7-1)) + 1)) + ) +) + +;------------------------------------------------------------- +; Immediates and displacements beyond the base insn +;------------------------------------------------------------- + +(df f-dsp-8-u6 "6 bit unsigned" (all-isas) 8 6 UINT #f #f) +(df f-dsp-8-u8 "8 bit unsigned" (all-isas) 8 8 UINT #f #f) +(df f-dsp-8-s8 "8 bit signed" (all-isas) 8 8 INT #f #f) +(df f-dsp-10-u6 "6 bit unsigned" (all-isas) 10 6 UINT #f #f) +(df f-dsp-16-u8 "8 bit unsigned" (all-isas) 16 8 UINT #f #f) +(df f-dsp-16-s8 "8 bit signed" (all-isas) 16 8 INT #f #f) +(df f-dsp-24-u8 "8 bit unsigned" (all-isas) 24 8 UINT #f #f) +(df f-dsp-24-s8 "8 bit signed" (all-isas) 24 8 INT #f #f) +(df f-dsp-32-u8 "8 bit unsigned" (all-isas) 32 8 UINT #f #f) +(df f-dsp-32-s8 "8 bit signed" (all-isas) 32 8 INT #f #f) +(df f-dsp-40-u8 "8 bit unsigned" (all-isas) 40 8 UINT #f #f) +(df f-dsp-40-s8 "8 bit signed" (all-isas) 40 8 INT #f #f) +(df f-dsp-48-u8 "8 bit unsigned" (all-isas) 48 8 UINT #f #f) +(df f-dsp-48-s8 "8 bit signed" (all-isas) 48 8 INT #f #f) +(df f-dsp-56-u8 "8 bit unsigned" (all-isas) 56 8 UINT #f #f) +(df f-dsp-56-s8 "8 bit signed" (all-isas) 56 8 INT #f #f) +(df f-dsp-64-u8 "8 bit unsigned" (all-isas) 64 8 UINT #f #f) +(df f-dsp-64-s8 "8 bit signed" (all-isas) 64 8 INT #f #f) + +; Insn opcode endianness is big, but the immediate fields are stored +; in little endian. Handle this here at the field level for all immediate +; fields longer that 1 byte. +; +; CGEN can't handle a field which spans a 32 bit word boundary, so +; handle those as multi ifields. +; +; Take care in expressions using 'srl' or 'sll' as part of some larger +; expression meant to yield sign-extended values. CGEN translates +; uses of those operators into C expressions whose type is 'unsigned +; int', which tends to make the whole expression 'unsigned int'. +; Expressions like (set (ifield foo) X), however, just take X and +; store it in some member of 'struct cgen_fields', all of whose +; members are 'long'. On machines where 'long' is larger than +; 'unsigned int', assigning a "sign-extended" unsigned int to a long +; just produces a very large positive value. insert_normal will +; range-check the field's value and produce odd error messages like +; this: +; +; Error: operand out of range (4160684031 not between -2147483648 and 2147483647) `add.l #-265,-270[fb]' +; +; Annoyingly, the code will work fine on machines where 'long' and +; 'unsigned int' are the same size: the assignment will produce a +; negative number. +; +; Just tell yourself over and over: overflow detection is expensive, +; and you're glad C doesn't do it, because it never happens in real +; life. + +(df f-dsp-8-u16 "16 bit unsigned" (all-isas) 8 16 UINT + ((value pc) (or UHI + (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))) ; insert + ((value pc) (or UHI + (and UHI (srl UHI value 8) #x00ff) + (and UHI (sll UHI value 8) #xff00))) ; extract +) + +(df f-dsp-8-s16 "8 bit signed" (all-isas) 8 16 INT + ((value pc) (ext INT + (trunc HI + (or (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))))) ; insert + ((value pc) (ext INT + (trunc HI + (or (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))))) ; extract +) + +(df f-dsp-16-u16 "16 bit unsigned" (all-isas) 16 16 UINT + ((value pc) (or UHI + (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))) ; insert + ((value pc) (or UHI + (and UHI (srl UHI value 8) #x00ff) + (and UHI (sll UHI value 8) #xff00))) ; extract +) + +(df f-dsp-16-s16 "16 bit signed" (all-isas) 16 16 INT + ((value pc) (ext INT + (trunc HI + (or (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))))) ; insert + ((value pc) (ext INT + (trunc HI + (or (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))))) ; extract +) + +(dnmf f-dsp-24-u16 "16 bit unsigned" (all-isas) UINT + (f-dsp-24-u8 f-dsp-32-u8) + (sequence () ; insert + (set (ifield f-dsp-24-u8) (and (ifield f-dsp-24-u16) #xff)) + (set (ifield f-dsp-32-u8) (and (srl (ifield f-dsp-24-u16) 8) #xff)) + ) + (sequence () ; extract + (set (ifield f-dsp-24-u16) (or (sll (ifield f-dsp-32-u8) 8) + (ifield f-dsp-24-u8))) + ) +) + +(dnmf f-dsp-24-s16 "16 bit signed" (all-isas) INT + (f-dsp-24-u8 f-dsp-32-u8) + (sequence () ; insert + (set (ifield f-dsp-24-u8) + (and (ifield f-dsp-24-s16) #xff)) + (set (ifield f-dsp-32-u8) + (and (srl (ifield f-dsp-24-s16) 8) #xff)) + ) + (sequence () ; extract + (set (ifield f-dsp-24-s16) + (ext INT + (trunc HI (or (sll (ifield f-dsp-32-u8) 8) + (ifield f-dsp-24-u8))))) + ) +) + +(df f-dsp-32-u16 "16 bit unsigned" (all-isas) 32 16 UINT + ((value pc) (or UHI + (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))) ; insert + ((value pc) (or UHI + (and UHI (srl UHI value 8) #x00ff) + (and UHI (sll UHI value 8) #xff00))) ; extract +) + +(df f-dsp-32-s16 "16 bit signed" (all-isas) 32 16 INT + ((value pc) (ext INT + (trunc HI + (or (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))))) ; insert + ((value pc) (ext INT + (trunc HI + (or (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))))) ; extract +) + +(df f-dsp-40-u16 "16 bit unsigned" (all-isas) 40 16 UINT + ((value pc) (or UHI + (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))) ; insert + ((value pc) (or UHI + (and UHI (srl UHI value 8) #x00ff) + (and UHI (sll UHI value 8) #xff00))) ; extract +) + +(df f-dsp-40-s16 "16 bit signed" (all-isas) 40 16 INT + ((value pc) (ext INT + (trunc HI + (or (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))))) ; insert + ((value pc) (ext INT + (trunc HI + (or (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))))) ; extract +) + +(df f-dsp-48-u16 "16 bit unsigned" (all-isas) 48 16 UINT + ((value pc) (or UHI + (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))) ; insert + ((value pc) (or UHI + (and UHI (srl UHI value 8) #x00ff) + (and UHI (sll UHI value 8) #xff00))) ; extract +) + +(df f-dsp-48-s16 "16 bit signed" (all-isas) 48 16 INT + ((value pc) (ext INT + (trunc HI + (or (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))))) ; insert + ((value pc) (ext INT + (trunc HI + (or (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))))) ; extract +) + +(df f-dsp-64-u16 "16 bit unsigned" (all-isas) 64 16 UINT + ((value pc) (or UHI + (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))) ; insert + ((value pc) (or UHI + (and UHI (srl UHI value 8) #x00ff) + (and UHI (sll UHI value 8) #xff00))) ; extract +) +(df f-dsp-8-s24 "24 bit signed" (all-isas) 8 24 INT + ((value pc) (or SI + (or (srl value 16) (and value #xff00)) + (sll (ext INT (trunc QI (and value #xff))) 16))) + ((value pc) (or SI + (or (srl value 16) (and value #xff00)) + (sll (ext INT (trunc QI (and value #xff))) 16))) + ) + +(df f-dsp-8-u24 "24 bit unsigned" (all-isas) 8 24 UINT + ((value pc) (or SI + (or (srl value 16) (and value #xff00)) + (sll (and value #xff) 16))) + ((value pc) (or SI + (or (srl value 16) (and value #xff00)) + (sll (and value #xff) 16))) + ) + +(dnmf f-dsp-16-u24 "24 bit unsigned" (all-isas) UINT + (f-dsp-16-u16 f-dsp-32-u8) + (sequence () ; insert + (set (ifield f-dsp-16-u16) (and (ifield f-dsp-16-u24) #xffff)) + (set (ifield f-dsp-32-u8) (and (srl (ifield f-dsp-16-u24) 16) #xff)) + ) + (sequence () ; extract + (set (ifield f-dsp-16-u24) (or (sll (ifield f-dsp-32-u8) 16) + (ifield f-dsp-16-u16))) + ) +) + +(dnmf f-dsp-24-u24 "24 bit unsigned" (all-isas) UINT + (f-dsp-24-u8 f-dsp-32-u16) + (sequence () ; insert + (set (ifield f-dsp-24-u8) (and (ifield f-dsp-24-u24) #xff)) + (set (ifield f-dsp-32-u16) (and (srl (ifield f-dsp-24-u24) 8) #xffff)) + ) + (sequence () ; extract + (set (ifield f-dsp-24-u24) (or (sll (ifield f-dsp-32-u16) 8) + (ifield f-dsp-24-u8))) + ) +) + +(df f-dsp-32-u24 "24 bit unsigned" (all-isas) 32 24 UINT + ((value pc) (or USI + (or USI + (and (srl value 16) #x0000ff) + (and value #x00ff00)) + (and (sll value 16) #xff0000))) ; insert + ((value pc) (or USI + (or USI + (and USI (srl UHI value 16) #x0000ff) + (and USI value #x00ff00)) + (and USI (sll UHI value 16) #xff0000))) ; extract +) + +(df f-dsp-40-u20 "20 bit unsigned" (all-isas) 40 20 UINT + ((value pc) (or USI + (or USI + (and (srl value 16) #x0000ff) + (and value #x00ff00)) + (and (sll value 16) #x0f0000))) ; insert + ((value pc) (or USI + (or USI + (and USI (srl UHI value 16) #x0000ff) + (and USI value #x00ff00)) + (and USI (sll UHI value 16) #x0f0000))) ; extract +) +(df f-dsp-40-u24 "24 bit unsigned" (all-isas) 40 24 UINT + ((value pc) (or USI + (or USI + (and (srl value 16) #x0000ff) + (and value #x00ff00)) + (and (sll value 16) #xff0000))) ; insert + ((value pc) (or USI + (or USI + (and USI (srl UHI value 16) #x0000ff) + (and USI value #x00ff00)) + (and USI (sll UHI value 16) #xff0000))) ; extract +) + +(dnmf f-dsp-40-s32 "32 bit signed" (all-isas) INT + (f-dsp-40-u24 f-dsp-64-u8) + (sequence () ; insert + (set (ifield f-dsp-64-u8) (and (srl (ifield f-dsp-40-s32) 24) #xff)) + (set (ifield f-dsp-40-u24) (and (ifield f-dsp-40-s32) #xffffff)) + ) + (sequence () ; extract + (set (ifield f-dsp-40-s32) (or (and (ifield f-dsp-40-u24) #xffffff) + (and (sll (ifield f-dsp-64-u8) 24) #xff000000))) + ) +) + +(dnmf f-dsp-48-u20 "20 bit unsigned" (all-isas) UINT + (f-dsp-48-u16 f-dsp-64-u8) + (sequence () ; insert + (set (ifield f-dsp-64-u8) (and (srl (ifield f-dsp-48-u20) 16) #x0f)) + (set (ifield f-dsp-48-u16) (and (ifield f-dsp-48-u20) #xffff)) + ) + (sequence () ; extract + (set (ifield f-dsp-48-u20) (or (and (ifield f-dsp-48-u16) #xffff) + (and (sll (ifield f-dsp-64-u8) 16) #x0f0000))) + ) +) +(dnmf f-dsp-48-u24 "24 bit unsigned" (all-isas) UINT + (f-dsp-48-u16 f-dsp-64-u8) + (sequence () ; insert + (set (ifield f-dsp-64-u8) (and (srl (ifield f-dsp-48-u24) 16) #xff)) + (set (ifield f-dsp-48-u16) (and (ifield f-dsp-48-u24) #xffff)) + ) + (sequence () ; extract + (set (ifield f-dsp-48-u24) (or (and (ifield f-dsp-48-u16) #xffff) + (and (sll (ifield f-dsp-64-u8) 16) #xff0000))) + ) +) + +(dnmf f-dsp-16-s32 "32 bit signed" (all-isas) INT + (f-dsp-16-u16 f-dsp-32-u16) + (sequence () ; insert + (set (ifield f-dsp-32-u16) (and (srl (ifield f-dsp-16-s32) 16) #xffff)) + (set (ifield f-dsp-16-u16) (and (ifield f-dsp-16-s32) #xffff)) + ) + (sequence () ; extract + (set (ifield f-dsp-16-s32) (or (and (ifield f-dsp-16-u16) #xffff) + (and (sll (ifield f-dsp-32-u16) 16) #xffff0000))) + ) +) + +(dnmf f-dsp-24-s32 "32 bit signed" (all-isas) INT + (f-dsp-24-u8 f-dsp-32-u24) + (sequence () ; insert + (set (ifield f-dsp-32-u24) (and (srl (ifield f-dsp-24-s32) 8) #xffffff)) + (set (ifield f-dsp-24-u8) (and (ifield f-dsp-24-s32) #xff)) + ) + (sequence () ; extract + (set (ifield f-dsp-24-s32) (or (and (ifield f-dsp-24-u8) #xff) + (and (sll (ifield f-dsp-32-u24) 8) #xffffff00))) + ) +) + +(df f-dsp-32-s32 "32 bit signed" (all-isas) 32 32 INT + ((value pc) + + ;; insert + (ext INT + (or SI + (or SI + (and (srl value 24) #x000000ff) + (and (srl value 8) #x0000ff00)) + (or SI + (and (sll value 8) #x00ff0000) + (and (sll value 24) #xff000000))))) + + ;; extract + ((value pc) + (ext INT + (or SI + (or SI + (and (srl value 24) #x000000ff) + (and (srl value 8) #x0000ff00)) + (or SI + (and (sll value 8) #x00ff0000) + (and (sll value 24) #xff000000))))) +) + +(dnmf f-dsp-48-u32 "32 bit unsigned" (all-isas) UINT + (f-dsp-48-u16 f-dsp-64-u16) + (sequence () ; insert + (set (ifield f-dsp-64-u16) (and (srl (ifield f-dsp-48-u32) 16) #xffff)) + (set (ifield f-dsp-48-u16) (and (ifield f-dsp-48-u32) #xffff)) + ) + (sequence () ; extract + (set (ifield f-dsp-48-u32) (or (and (ifield f-dsp-48-u16) #xffff) + (and (sll (ifield f-dsp-64-u16) 16) #xffff0000))) + ) +) + +(dnmf f-dsp-48-s32 "32 bit signed" (all-isas) INT + (f-dsp-48-u16 f-dsp-64-u16) + (sequence () ; insert + (set (ifield f-dsp-64-u16) (and (srl (ifield f-dsp-48-s32) 16) #xffff)) + (set (ifield f-dsp-48-u16) (and (ifield f-dsp-48-s32) #xffff)) + ) + (sequence () ; extract + (set (ifield f-dsp-48-s32) (or (and (ifield f-dsp-48-u16) #xffff) + (and (sll (ifield f-dsp-64-u16) 16) #xffff0000))) + ) +) + +(dnmf f-dsp-56-s16 "16 bit signed" (all-isas) INT + (f-dsp-56-u8 f-dsp-64-u8) + (sequence () ; insert + (set (ifield f-dsp-56-u8) + (and (ifield f-dsp-56-s16) #xff)) + (set (ifield f-dsp-64-u8) + (and (srl (ifield f-dsp-56-s16) 8) #xff)) + ) + (sequence () ; extract + (set (ifield f-dsp-56-s16) + (ext INT + (trunc HI (or (sll (ifield f-dsp-64-u8) 8) + (ifield f-dsp-56-u8))))) + ) +) + +(df f-dsp-64-s16 " 16 bit signed" (all-isas) 64 16 INT + ((value pc) (ext INT + (trunc HI + (or (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))))) ; insert + ((value pc) (ext INT + (trunc HI + (or (and (srl value 8) #x00ff) + (and (sll value 8) #xff00))))) ; extract +) + +;------------------------------------------------------------- +; Bit indices +;------------------------------------------------------------- + +(dnf f-bitno16-S "bit index for m16c" (all-isas) 5 3) +(dnf f-bitno32-prefixed "bit index for m32c" (all-isas) 21 3) +(dnf f-bitno32-unprefixed "bit index for m32c" (all-isas) 13 3) + +(dnmf f-bitbase16-u11-S "unsigned bit,base:11" (all-isas) UINT + (f-bitno16-S f-dsp-8-u8) + (sequence () ; insert + (set (ifield f-bitno16-S) (and f-bitbase16-u11-S #x7)) + (set (ifield f-dsp-8-u8) (and (srl (ifield f-bitbase16-u11-S) 3) #xff)) + ) + (sequence () ; extract + (set (ifield f-bitbase16-u11-S) (or (sll (ifield f-dsp-8-u8) 3) + (ifield f-bitno16-S))) + ) +) + +(dnmf f-bitbase32-16-u11-unprefixed "unsigned bit,base:11" (all-isas) UINT + (f-bitno32-unprefixed f-dsp-16-u8) + (sequence () ; insert + (set (ifield f-bitno32-unprefixed) (and f-bitbase32-16-u11-unprefixed #x7)) + (set (ifield f-dsp-16-u8) (and (srl (ifield f-bitbase32-16-u11-unprefixed) 3) #xff)) + ) + (sequence () ; extract + (set (ifield f-bitbase32-16-u11-unprefixed) (or (sll (ifield f-dsp-16-u8) 3) + (ifield f-bitno32-unprefixed))) + ) +) +(dnmf f-bitbase32-16-s11-unprefixed "signed bit,base:11" (all-isas) INT + (f-bitno32-unprefixed f-dsp-16-s8) + (sequence () ; insert + (set (ifield f-bitno32-unprefixed) (and f-bitbase32-16-s11-unprefixed #x7)) + (set (ifield f-dsp-16-s8) (sra INT (ifield f-bitbase32-16-s11-unprefixed) 3)) + ) + (sequence () ; extract + (set (ifield f-bitbase32-16-s11-unprefixed) (or (sll (ifield f-dsp-16-s8) 3) + (ifield f-bitno32-unprefixed))) + ) +) +(dnmf f-bitbase32-16-u19-unprefixed "unsigned bit,base:19" (all-isas) UINT + (f-bitno32-unprefixed f-dsp-16-u16) + (sequence () ; insert + (set (ifield f-bitno32-unprefixed) (and f-bitbase32-16-u19-unprefixed #x7)) + (set (ifield f-dsp-16-u16) (and (srl (ifield f-bitbase32-16-u19-unprefixed) 3) #xffff)) + ) + (sequence () ; extract + (set (ifield f-bitbase32-16-u19-unprefixed) (or (sll (ifield f-dsp-16-u16) 3) + (ifield f-bitno32-unprefixed))) + ) +) +(dnmf f-bitbase32-16-s19-unprefixed "signed bit,base:11" (all-isas) INT + (f-bitno32-unprefixed f-dsp-16-s16) + (sequence () ; insert + (set (ifield f-bitno32-unprefixed) (and f-bitbase32-16-s19-unprefixed #x7)) + (set (ifield f-dsp-16-s16) (sra INT (ifield f-bitbase32-16-s19-unprefixed) 3)) + ) + (sequence () ; extract + (set (ifield f-bitbase32-16-s19-unprefixed) (or (sll (ifield f-dsp-16-s16) 3) + (ifield f-bitno32-unprefixed))) + ) +) +; SID decoder doesn't handle multi-ifield referencing another multi-ifield :-( +(dnmf f-bitbase32-16-u27-unprefixed "unsigned bit,base:27" (all-isas) UINT + (f-bitno32-unprefixed f-dsp-16-u16 f-dsp-32-u8) + (sequence () ; insert + (set (ifield f-bitno32-unprefixed) (and f-bitbase32-16-u27-unprefixed #x7)) + (set (ifield f-dsp-16-u16) (and (srl (ifield f-bitbase32-16-u27-unprefixed) 3) #xffff)) + (set (ifield f-dsp-32-u8) (and (srl (ifield f-bitbase32-16-u27-unprefixed) 19) #xff)) + ) + (sequence () ; extract + (set (ifield f-bitbase32-16-u27-unprefixed) (or (sll (ifield f-dsp-16-u16) 3) + (or (sll (ifield f-dsp-32-u8) 19) + (ifield f-bitno32-unprefixed)))) + ) +) +(dnmf f-bitbase32-24-u11-prefixed "unsigned bit,base:11" (all-isas) UINT + (f-bitno32-prefixed f-dsp-24-u8) + (sequence () ; insert + (set (ifield f-bitno32-prefixed) (and f-bitbase32-24-u11-prefixed #x7)) + (set (ifield f-dsp-24-u8) (and (srl (ifield f-bitbase32-24-u11-prefixed) 3) #xff)) + ) + (sequence () ; extract + (set (ifield f-bitbase32-24-u11-prefixed) (or (sll (ifield f-dsp-24-u8) 3) + (ifield f-bitno32-prefixed))) + ) +) +(dnmf f-bitbase32-24-s11-prefixed "signed bit,base:11" (all-isas) INT + (f-bitno32-prefixed f-dsp-24-s8) + (sequence () ; insert + (set (ifield f-bitno32-prefixed) (and f-bitbase32-24-s11-prefixed #x7)) + (set (ifield f-dsp-24-s8) (sra INT (ifield f-bitbase32-24-s11-prefixed) 3)) + ) + (sequence () ; extract + (set (ifield f-bitbase32-24-s11-prefixed) (or (sll (ifield f-dsp-24-s8) 3) + (ifield f-bitno32-prefixed))) + ) +) +; SID decoder doesn't handle multi-ifield referencing another multi-ifield :-( +(dnmf f-bitbase32-24-u19-prefixed "unsigned bit,base:19" (all-isas) UINT + (f-bitno32-prefixed f-dsp-24-u8 f-dsp-32-u8) + (sequence () ; insert + (set (ifield f-bitno32-prefixed) (and f-bitbase32-24-u19-prefixed #x7)) + (set (ifield f-dsp-24-u8) (and (srl (ifield f-bitbase32-24-u19-prefixed) 3) #xff)) + (set (ifield f-dsp-32-u8) (and (srl (ifield f-bitbase32-24-u19-prefixed) 11) #xff)) + ) + (sequence () ; extract + (set (ifield f-bitbase32-24-u19-prefixed) (or (sll (ifield f-dsp-24-u8) 3) + (or (sll (ifield f-dsp-32-u8) 11) + (ifield f-bitno32-prefixed)))) + ) +) +; SID decoder doesn't handle multi-ifield referencing another multi-ifield :-( +(dnmf f-bitbase32-24-s19-prefixed "signed bit,base:11" (all-isas) INT + (f-bitno32-prefixed f-dsp-24-u8 f-dsp-32-s8) + (sequence () ; insert + (set (ifield f-bitno32-prefixed) (and f-bitbase32-24-s19-prefixed #x7)) + (set (ifield f-dsp-24-u8) (and (srl (ifield f-bitbase32-24-s19-prefixed) 3) #xff)) + (set (ifield f-dsp-32-s8) (sra INT (ifield f-bitbase32-24-s19-prefixed) 11)) + ) + (sequence () ; extract + (set (ifield f-bitbase32-24-s19-prefixed) (or (sll (ifield f-dsp-24-u8) 3) + (or (sll (ifield f-dsp-32-s8) 11) + (ifield f-bitno32-prefixed)))) + ) +) +; SID decoder doesn't handle multi-ifield referencing another multi-ifield :-( +(dnmf f-bitbase32-24-u27-prefixed "unsigned bit,base:27" (all-isas) UINT + (f-bitno32-prefixed f-dsp-24-u8 f-dsp-32-u16) + (sequence () ; insert + (set (ifield f-bitno32-prefixed) (and f-bitbase32-24-u27-prefixed #x7)) + (set (ifield f-dsp-24-u8) (and (srl (ifield f-bitbase32-24-u27-prefixed) 3) #xff)) + (set (ifield f-dsp-32-u16) (and (srl (ifield f-bitbase32-24-u27-prefixed) 11) #xffff)) + ) + (sequence () ; extract + (set (ifield f-bitbase32-24-u27-prefixed) (or (sll (ifield f-dsp-24-u8) 3) + (or (sll (ifield f-dsp-32-u16) 11) + (ifield f-bitno32-prefixed)))) + ) +) + +;------------------------------------------------------------- +; Labels +;------------------------------------------------------------- + +(df f-lab-5-3 "3 bit pc relative unsigned offset" (PCREL-ADDR all-isas) 5 3 UINT + ((value pc) (sub SI value (add SI pc 2))) ; insert + ((value pc) (add SI value (add SI pc 2))) ; extract +) +(dnmf f-lab32-jmp-s "unsigned 3 bit pc relative offset" (PCREL-ADDR all-isas) UINT + (f-2-2 f-7-1) + (sequence ((SI val)) ; insert + (set val (sub (sub (ifield f-lab32-jmp-s) pc) 2)) + (set (ifield f-7-1) (and val #x1)) + (set (ifield f-2-2) (srl val 1)) + ) + (sequence () ; extract + (set (ifield f-lab32-jmp-s) (add pc (add (or (sll (ifield f-2-2) 1) + (ifield f-7-1)) + 2))) + ) +) +(df f-lab-8-8 "8 bit pc relative signed offset" (PCREL-ADDR all-isas) 8 8 INT + ((value pc) (sub SI value (add SI pc 1))) ; insert + ((value pc) (add SI value (add SI pc 1))) ; extract +) +(df f-lab-8-16 "16 bit pc relative signed offset" (PCREL-ADDR SIGN-OPT all-isas) 8 16 UINT + ((value pc) (or SI (sll (and (sub value (add pc 1)) #xff) 8) + (srl (and (sub value (add pc 1)) #xffff) 8))) + ((value pc) (add SI (or (srl (and value #xffff) 8) + (sra (sll (and value #xff) 24) 16)) (add pc 1))) + ) +(df f-lab-8-24 "24 bit absolute" (all-isas ABS-ADDR) 8 24 UINT + ((value pc) (or SI + (or (srl value 16) (and value #xff00)) + (sll (and value #xff) 16))) + ((value pc) (or SI + (or (srl value 16) (and value #xff00)) + (sll (and value #xff) 16))) + ) +(df f-lab-16-8 "8 bit pc relative signed offset" (PCREL-ADDR all-isas) 16 8 INT + ((value pc) (sub SI value (add SI pc 2))) ; insert + ((value pc) (add SI value (add SI pc 2))) ; extract +) +(df f-lab-24-8 "8 bit pc relative signed offset" (PCREL-ADDR all-isas) 24 8 INT + ((value pc) (sub SI value (add SI pc 2))) ; insert + ((value pc) (add SI value (add SI pc 2))) ; extract +) +(df f-lab-32-8 "8 bit pc relative signed offset" (PCREL-ADDR all-isas) 32 8 INT + ((value pc) (sub SI value (add SI pc 2))) ; insert + ((value pc) (add SI value (add SI pc 2))) ; extract +) +(df f-lab-40-8 "8 bit pc relative signed offset" (PCREL-ADDR all-isas) 40 8 INT + ((value pc) (sub SI value (add SI pc 2))) ; insert + ((value pc) (add SI value (add SI pc 2))) ; extract +) + +;------------------------------------------------------------- +; Condition codes +;------------------------------------------------------------- + +(dnf f-cond16 "condition code" (all-isas) 12 4) +(dnf f-cond16j-5 "condition code" (all-isas) 5 3) + +(dnmf f-cond32 "condition code" (all-isas) UINT + (f-9-1 f-13-3) + (sequence () ; insert + (set (ifield f-9-1) (and (srl (ifield f-cond32) 3) 1)) + (set (ifield f-13-3) (and (ifield f-cond32) #x7)) + ) + (sequence () ; extract + (set (ifield f-cond32) (or (sll (ifield f-9-1) 3) + (ifield f-13-3))) + ) +) + +(dnmf f-cond32j "condition code" (all-isas) UINT + (f-1-3 f-7-1) + (sequence () ; insert + (set (ifield f-1-3) (and (srl (ifield f-cond32j) 1) #x7)) + (set (ifield f-7-1) (and (ifield f-cond32j) #x1)) + ) + (sequence () ; extract + (set (ifield f-cond32j) (or (sll (ifield f-1-3) 1) + (ifield f-7-1))) + ) +) + +;============================================================= +; Hardware +; +(dnh h-pc "program counter" (PC all-isas) (pc USI) () () ()) + +;------------------------------------------------------------- +; General registers +; The actual registers are 16 bits +;------------------------------------------------------------- + +(define-hardware + (name h-gr) + (comment "general 16 bit registers") + (attrs all-isas CACHE-ADDR) + (type register HI (4)) + (indices keyword "" (("r0" 0) ("r1" 1) ("r2" 2) ("r3" 3)))) + +; Define different views of the grs as VIRTUAL with getter/setter specs +; +(define-hardware + (name h-gr-QI) + (comment "general 8 bit registers") + (attrs all-isas VIRTUAL) + (type register QI (4)) + (indices keyword "" (("r0l" 0) ("r0h" 1) ("r1l" 2) ("r1h" 3))) + (get (index) (and (if SI (mod index 2) + (srl (reg h-gr (div index 2)) 8) + (reg h-gr (div index 2))) + #xff)) + (set (index newval) (set (reg h-gr (div index 2)) + (if SI (mod index 2) + (or (and (reg h-gr (div index 2)) #xff) + (sll (and newval #xff) 8)) + (or (and (reg h-gr (div index 2)) #xff00) + (and newval #xff)))))) + +(define-hardware + (name h-gr-HI) + (comment "general 16 bit registers") + (attrs all-isas VIRTUAL) + (type register HI (4)) + (indices keyword "" (("r0" 0) ("r1" 1) ("r2" 2) ("r3" 3))) + (get (index) (reg h-gr index)) + (set (index newval) (set (reg h-gr index) newval))) + +(define-hardware + (name h-gr-SI) + (comment "general 32 bit registers") + (attrs all-isas VIRTUAL) + (type register SI (2)) + (indices keyword "" (("r2r0" 0) ("r3r1" 1))) + (get (index) (or SI + (and (reg h-gr index) #xffff) + (and (sll (reg h-gr (add index 2)) 16) #xffff0000))) + (set (index newval) (sequence () + (set (reg h-gr index) (and newval #xffff)) + (set (reg h-gr (add index 2)) (srl newval 16))))) + +(define-hardware + (name h-gr-ext-QI) + (comment "general 16 bit registers") + (attrs all-isas VIRTUAL) + (type register HI (2)) + (indices keyword "" (("r0l" 0) ("r1l" 1))) + (get (index) (reg h-gr-QI (mul index 2))) + (set (index newval) (set (reg h-gr (mul index 2)) newval))) + +(define-hardware + (name h-gr-ext-HI) + (comment "general 16 bit registers") + (attrs all-isas VIRTUAL) + (type register SI (2)) + (indices keyword "" (("r0" 0) ("r1" 1))) + (get (index) (reg h-gr (mul index 2))) + (set (index newval) (set (reg h-gr-SI index) newval))) + +(define-hardware + (name h-r0l) + (comment "r0l register") + (attrs all-isas VIRTUAL) + (type register QI) + (indices keyword "" (("r0l" 0))) + (get () (reg h-gr-QI 0)) + (set (newval) (set (reg h-gr-QI 0) newval))) + +(define-hardware + (name h-r0h) + (comment "r0h register") + (attrs all-isas VIRTUAL) + (type register QI) + (indices keyword "" (("r0h" 0))) + (get () (reg h-gr-QI 1)) + (set (newval) (set (reg h-gr-QI 1) newval))) + +(define-hardware + (name h-r1l) + (comment "r1l register") + (attrs all-isas VIRTUAL) + (type register QI) + (indices keyword "" (("r1l" 0))) + (get () (reg h-gr-QI 2)) + (set (newval) (set (reg h-gr-QI 2) newval))) + +(define-hardware + (name h-r1h) + (comment "r1h register") + (attrs all-isas VIRTUAL) + (type register QI) + (indices keyword "" (("r1h" 0))) + (get () (reg h-gr-QI 3)) + (set (newval) (set (reg h-gr-QI 3) newval))) + +(define-hardware + (name h-r0) + (comment "r0 register") + (attrs all-isas VIRTUAL) + (type register HI) + (indices keyword "" (("r0" 0))) + (get () (reg h-gr 0)) + (set (newval) (set (reg h-gr 0) newval))) + +(define-hardware + (name h-r1) + (comment "r1 register") + (attrs all-isas VIRTUAL) + (type register HI) + (indices keyword "" (("r1" 0))) + (get () (reg h-gr 1)) + (set (newval) (set (reg h-gr 1) newval))) + +(define-hardware + (name h-r2) + (comment "r2 register") + (attrs all-isas VIRTUAL) + (type register HI) + (indices keyword "" (("r2" 0))) + (get () (reg h-gr 2)) + (set (newval) (set (reg h-gr 2) newval))) + +(define-hardware + (name h-r3) + (comment "r3 register") + (attrs all-isas VIRTUAL) + (type register HI) + (indices keyword "" (("r3" 0))) + (get () (reg h-gr 3)) + (set (newval) (set (reg h-gr 3) newval))) + +(define-hardware + (name h-r0l-r0h) + (comment "r0l or r0h") + (attrs all-isas VIRTUAL) + (type register QI (2)) + (indices keyword "" (("r0l" 0) ("r0h" 1))) + (get (index) (reg h-gr-QI index)) + (set (index newval) (set (reg h-gr-QI index) newval))) + +(define-hardware + (name h-r2r0) + (comment "r2r0 register") + (attrs all-isas VIRTUAL) + (type register SI) + (indices keyword "" (("r2r0" 0))) + (get () (or (sll (reg h-gr 2) 16) (reg h-gr 0))) + (set (newval) + (sequence () + (set (reg h-gr 0) newval) + (set (reg h-gr 2) (sra newval 16))))) + +(define-hardware + (name h-r3r1) + (comment "r3r1 register") + (attrs all-isas VIRTUAL) + (type register SI) + (indices keyword "" (("r3r1" 0))) + (get () (or (sll (reg h-gr 3) 16) (reg h-gr 1))) + (set (newval) + (sequence () + (set (reg h-gr 1) newval) + (set (reg h-gr 3) (sra newval 16))))) + +(define-hardware + (name h-r1r2r0) + (comment "r1r2r0 register") + (attrs all-isas VIRTUAL) + (type register DI) + (indices keyword "" (("r1r2r0" 0))) + (get () (or DI (sll DI (reg h-gr 1) 32) (or (sll (reg h-gr 2) 16) (reg h-gr 0)))) + (set (newval) + (sequence () + (set (reg h-gr 0) newval) + (set (reg h-gr 2) (sra newval 16)) + (set (reg h-gr 1) (sra newval 32))))) + +;------------------------------------------------------------- +; Address registers +;------------------------------------------------------------- + +(define-hardware + (name h-ar) + (comment "address registers") + (attrs all-isas) + (type register USI (2)) + (indices keyword "" (("a0" 0) ("a1" 1))) + (get (index) (c-call USI "h_ar_get_handler" index)) + (set (index newval) (c-call VOID "h_ar_set_handler" index newval))) + +; Define different views of the ars as VIRTUAL with getter/setter specs +(define-hardware + (name h-ar-QI) + (comment "8 bit view of address register") + (attrs all-isas VIRTUAL) + (type register QI (2)) + (indices keyword "" (("a0" 0) ("a1" 1))) + (get (index) (reg h-ar index)) + (set (index newval) (set (reg h-ar index) newval))) + +(define-hardware + (name h-ar-HI) + (comment "16 bit view of address register") + (attrs all-isas VIRTUAL) + (type register HI (2)) + (indices keyword "" (("a0" 0) ("a1" 1))) + (get (index) (reg h-ar index)) + (set (index newval) (set (reg h-ar index) newval))) + +(define-hardware + (name h-ar-SI) + (comment "32 bit view of address register") + (attrs all-isas VIRTUAL) + (type register SI) + (indices keyword "" (("a1a0" 0))) + (get () (or SI (sll SI (ext SI (reg h-ar 1)) 16) (ext SI (reg h-ar 0)))) + (set (newval) (sequence () + (set (reg h-ar 0) (and newval #xffff)) + (set (reg h-ar 1) (and (srl newval 16) #xffff))))) + +(define-hardware + (name h-a0) + (comment "16 bit view of address register") + (attrs all-isas VIRTUAL) + (type register HI) + (indices keyword "" (("a0" 0))) + (get () (reg h-ar 0)) + (set (newval) (set (reg h-ar 0) newval))) + +(define-hardware + (name h-a1) + (comment "16 bit view of address register") + (attrs all-isas VIRTUAL) + (type register HI) + (indices keyword "" (("a1" 1))) + (get () (reg h-ar 1)) + (set (newval) (set (reg h-ar 1) newval))) + +; SB Register +(define-hardware + (name h-sb) + (comment "SB register") + (attrs all-isas) + (type register USI) + (get () (c-call USI "h_sb_get_handler")) + (set (newval) (c-call VOID "h_sb_set_handler" newval)) +) + +; FB Register +(define-hardware + (name h-fb) + (comment "FB register") + (attrs all-isas) + (type register USI) + (get () (c-call USI "h_fb_get_handler")) + (set (newval) (c-call VOID "h_fb_set_handler" newval)) +) + +; SP Register +(define-hardware + (name h-sp) + (comment "SP register") + (attrs all-isas) + (type register USI) + (get () (c-call USI "h_sp_get_handler")) + (set (newval) (c-call VOID "h_sp_set_handler" newval)) +) + +;------------------------------------------------------------- +; condition-code bits +;------------------------------------------------------------- + +(define-hardware + (name h-sbit) + (comment "sign bit") + (attrs all-isas) + (type register BI) +) + +(define-hardware + (name h-zbit) + (comment "zero bit") + (attrs all-isas) + (type register BI) +) + +(define-hardware + (name h-obit) + (comment "overflow bit") + (attrs all-isas) + (type register BI) +) + +(define-hardware + (name h-cbit) + (comment "carry bit") + (attrs all-isas) + (type register BI) +) + +(define-hardware + (name h-ubit) + (comment "stack pointer select bit") + (attrs all-isas) + (type register BI) +) + +(define-hardware + (name h-ibit) + (comment "interrupt enable bit") + (attrs all-isas) + (type register BI) +) + +(define-hardware + (name h-bbit) + (comment "register bank select bit") + (attrs all-isas) + (type register BI) +) + +(define-hardware + (name h-dbit) + (comment "debug bit") + (attrs all-isas) + (type register BI) +) + +(define-hardware + (name h-dct0) + (comment "dma transfer count 000") + (attrs all-isas) + (type register UHI) +) +(define-hardware + (name h-dct1) + (comment "dma transfer count 001") + (attrs all-isas) + (type register UHI) +) +(define-hardware + (name h-svf) + (comment "save flag 011") + (attrs all-isas) + (type register UHI) +) +(define-hardware + (name h-drc0) + (comment "dma transfer count reload 100") + (attrs all-isas) + (type register UHI) +) +(define-hardware + (name h-drc1) + (comment "dma transfer count reload 101") + (attrs all-isas) + (type register UHI) +) +(define-hardware + (name h-dmd0) + (comment "dma mode 110") + (attrs all-isas) + (type register UQI) +) +(define-hardware + (name h-dmd1) + (comment "dma mode 111") + (attrs all-isas) + (type register UQI) +) +(define-hardware + (name h-intb) + (comment "interrupt table 000") + (attrs all-isas) + (type register USI) +) +(define-hardware + (name h-svp) + (comment "save pc 100") + (attrs all-isas) + (type register UHI) +) +(define-hardware + (name h-vct) + (comment "vector 101") + (attrs all-isas) + (type register USI) +) +(define-hardware + (name h-isp) + (comment "interrupt stack ptr 111") + (attrs all-isas) + (type register USI) +) +(define-hardware + (name h-dma0) + (comment "dma mem addr 010") + (attrs all-isas) + (type register USI) +) +(define-hardware + (name h-dma1) + (comment "dma mem addr 011") + (attrs all-isas) + (type register USI) +) +(define-hardware + (name h-dra0) + (comment "dma mem addr reload 100") + (attrs all-isas) + (type register USI) +) +(define-hardware + (name h-dra1) + (comment "dma mem addr reload 101") + (attrs all-isas) + (type register USI) +) +(define-hardware + (name h-dsa0) + (comment "dma sfr addr 110") + (attrs all-isas) + (type register USI) +) +(define-hardware + (name h-dsa1) + (comment "dma sfr addr 111") + (attrs all-isas) + (type register USI) +) + +;------------------------------------------------------------- +; Condition code operand hardware +;------------------------------------------------------------- + +(define-hardware + (name h-cond16) + (comment "condition code hardware for m16c") + (attrs m16c-isa MACH16) + (type immediate UQI) + (values keyword "" + (("geu" #x00) ("c" #x00) + ("gtu" #x01) + ("eq" #x02) ("z" #x02) + ("n" #x03) + ("le" #x04) + ("o" #x05) + ("ge" #x06) + ("ltu" #xf8) ("nc" #xf8) + ("leu" #xf9) + ("ne" #xfa) ("nz" #xfa) + ("pz" #xfb) + ("gt" #xfc) + ("no" #xfd) + ("lt" #xfe) + ) + ) +) +(define-hardware + (name h-cond16c) + (comment "condition code hardware for m16c") + (attrs m16c-isa MACH16) + (type immediate UQI) + (values keyword "" + (("geu" #x00) ("c" #x00) + ("gtu" #x01) + ("eq" #x02) ("z" #x02) + ("n" #x03) + ("ltu" #x04) ("nc" #x04) + ("leu" #x05) + ("ne" #x06) ("nz" #x06) + ("pz" #x07) + ("le" #x08) + ("o" #x09) + ("ge" #x0a) + ("gt" #x0c) + ("no" #x0d) + ("lt" #x0e) + ) + ) +) +(define-hardware + (name h-cond16j) + (comment "condition code hardware for m16c") + (attrs m16c-isa MACH16) + (type immediate UQI) + (values keyword "" + (("le" #x08) + ("o" #x09) + ("ge" #x0a) + ("gt" #x0c) + ("no" #x0d) + ("lt" #x0e) + ) + ) +) +(define-hardware + (name h-cond16j-5) + (comment "condition code hardware for m16c") + (attrs m16c-isa MACH16) + (type immediate UQI) + (values keyword "" + (("geu" #x00) ("c" #x00) + ("gtu" #x01) + ("eq" #x02) ("z" #x02) + ("n" #x03) + ("ltu" #x04) ("nc" #x04) + ("leu" #x05) + ("ne" #x06) ("nz" #x06) + ("pz" #x07) + ) + ) +) + +(define-hardware + (name h-cond32) + (comment "condition code hardware for m32c") + (attrs m32c-isa MACH32) + (type immediate UQI) + (values keyword "" + (("ltu" #x00) ("nc" #x00) + ("leu" #x01) + ("ne" #x02) ("nz" #x02) + ("pz" #x03) + ("no" #x04) + ("gt" #x05) + ("ge" #x06) + ("geu" #x08) ("c" #x08) + ("gtu" #x09) + ("eq" #x0a) ("z" #x0a) + ("n" #x0b) + ("o" #x0c) + ("le" #x0d) + ("lt" #x0e) + ) + ) +) + +(define-hardware + (name h-cr1-32) + (comment "control registers") + (attrs m32c-isa MACH32) + (type immediate UQI) + (values keyword "" (("dct0" 0) ("dct1" 1) ("flg" 2) ("svf" 3) ("drc0" 4) + ("drc1" 5) ("dmd0" 6) ("dmd1" 7)))) +(define-hardware + (name h-cr2-32) + (comment "control registers") + (attrs m32c-isa MACH32) + (type immediate UQI) + (values keyword "" (("intb" 0) ("sp" 1) ("sb" 2) ("fb" 3) ("svp" 4) + ("vct" 5) ("isp" 7)))) + +(define-hardware + (name h-cr3-32) + (comment "control registers") + (attrs m32c-isa MACH32) + (type immediate UQI) + (values keyword "" (("dma0" 2) ("dma1" 3) ("dra0" 4) + ("dra1" 5) ("dsa0" 6) ("dsa1" 7)))) +(define-hardware + (name h-cr-16) + (comment "control registers") + (attrs m16c-isa MACH16) + (type immediate UQI) + (values keyword "" (("intbl" 1) ("intbh" 2) ("flg" 3) ("isp" 4) + ("sp" 5) ("sb" 6) ("fb" 7)))) + +(define-hardware + (name h-flags) + (comment "flag hardware for m32c") + (attrs all-isas) + (type immediate UQI) + (values keyword "" + (("c" #x0) + ("d" #x1) + ("z" #x2) + ("s" #x3) + ("b" #x4) + ("o" #x5) + ("i" #x6) + ("u" #x7) + ) + ) +) + +;------------------------------------------------------------- +; Misc helper hardware +;------------------------------------------------------------- + +(define-hardware + (name h-shimm) + (comment "shift immediate") + (attrs all-isas) + (type immediate (INT 4)) + (values keyword "" (("1" 0) ("2" 1) ("3" 2) ("4" 3) ("5" 4) ("6" 5) ("7" 6) + ("8" 7) ("-1" -8) ("-2" -7) ("-3" -6) ("-4" -5) ("-5" -4) + ("-6" -3) ("-7" -2) ("-8" -1) + ))) +(define-hardware + (name h-bit-index) + (comment "bit index for the next insn") + (attrs m32c-isa MACH32) + (type register UHI) +) +(define-hardware + (name h-src-index) + (comment "source index for the next insn") + (attrs m32c-isa MACH32) + (type register UHI) +) +(define-hardware + (name h-dst-index) + (comment "destination index for the next insn") + (attrs m32c-isa MACH32) + (type register UHI) +) +(define-hardware + (name h-src-indirect) + (comment "indirect src for the next insn") + (attrs all-isas) + (type register UHI) +) +(define-hardware + (name h-dst-indirect) + (comment "indirect dst for the next insn") + (attrs all-isas) + (type register UHI) +) +(define-hardware + (name h-none) + (comment "for storing unused values") + (attrs m32c-isa MACH32) + (type register SI) +) + +;============================================================= +; Operands +;------------------------------------------------------------- +; Source Registers +;------------------------------------------------------------- + +(dnop Src16RnQI "general register QI view" (MACH16 m16c-isa) h-gr-QI f-src16-rn) +(dnop Src16RnHI "general register QH view" (MACH16 m16c-isa) h-gr-HI f-src16-rn) + +(dnop Src32RnUnprefixedQI "general register QI view" (MACH32 m32c-isa) h-gr-QI f-src32-rn-unprefixed-QI) +(dnop Src32RnUnprefixedHI "general register HI view" (MACH32 m32c-isa) h-gr-HI f-src32-rn-unprefixed-HI) +(dnop Src32RnUnprefixedSI "general register SI view" (MACH32 m32c-isa) h-gr-SI f-src32-rn-unprefixed-SI) + +(dnop Src32RnPrefixedQI "general register QI view" (MACH32 m32c-isa) h-gr-QI f-src32-rn-prefixed-QI) +(dnop Src32RnPrefixedHI "general register HI view" (MACH32 m32c-isa) h-gr-HI f-src32-rn-prefixed-HI) +(dnop Src32RnPrefixedSI "general register SI view" (MACH32 m32c-isa) h-gr-SI f-src32-rn-prefixed-SI) + +(dnop Src16An "address register" (MACH16 m16c-isa) h-ar f-src16-an) +(dnop Src16AnQI "address register QI view" (MACH16 m16c-isa) h-ar-QI f-src16-an) +(dnop Src16AnHI "address register HI view" (MACH16 m16c-isa) h-ar-HI f-src16-an) + +(dnop Src32AnUnprefixed "address register" (MACH32 m32c-isa) h-ar f-src32-an-unprefixed) +(dnop Src32AnUnprefixedQI "address register QI view" (MACH32 m32c-isa) h-ar-QI f-src32-an-unprefixed) +(dnop Src32AnUnprefixedHI "address register HI view" (MACH32 m32c-isa) h-ar-HI f-src32-an-unprefixed) +(dnop Src32AnUnprefixedSI "address register SI view" (MACH32 m32c-isa) h-ar f-src32-an-unprefixed) + +(dnop Src32AnPrefixed "address register" (MACH32 m32c-isa) h-ar f-src32-an-prefixed) +(dnop Src32AnPrefixedQI "address register QI view" (MACH32 m32c-isa) h-ar-QI f-src32-an-prefixed) +(dnop Src32AnPrefixedHI "address register HI view" (MACH32 m32c-isa) h-ar-HI f-src32-an-prefixed) +(dnop Src32AnPrefixedSI "address register SI view" (MACH32 m32c-isa) h-ar f-src32-an-prefixed) + +; Destination Registers +; +(dnop Dst16RnQI "general register QI view" (MACH16 m16c-isa) h-gr-QI f-dst16-rn) +(dnop Dst16RnHI "general register HI view" (MACH16 m16c-isa) h-gr-HI f-dst16-rn) +(dnop Dst16RnSI "general register SI view" (MACH16 m16c-isa) h-gr-SI f-dst16-rn) +(dnop Dst16RnExtQI "general register QI/HI view for 'ext' insns" (MACH16 m16c-isa) h-gr-ext-QI f-dst16-rn-ext) + +(dnop Dst32R0QI-S "general register QI view" (MACH32 m32c-isa) h-r0l f-nil) +(dnop Dst32R0HI-S "general register HI view" (MACH32 m32c-isa) h-r0 f-nil) + +(dnop Dst32RnUnprefixedQI "general register QI view" (MACH32 m32c-isa) h-gr-QI f-dst32-rn-unprefixed-QI) +(dnop Dst32RnUnprefixedHI "general register HI view" (MACH32 m32c-isa) h-gr-HI f-dst32-rn-unprefixed-HI) +(dnop Dst32RnUnprefixedSI "general register SI view" (MACH32 m32c-isa) h-gr-SI f-dst32-rn-unprefixed-SI) +(dnop Dst32RnExtUnprefixedQI "general register QI view" (MACH32 m32c-isa) h-gr-ext-QI f-dst32-rn-ext-unprefixed) +(dnop Dst32RnExtUnprefixedHI "general register HI view" (MACH32 m32c-isa) h-gr-ext-HI f-dst32-rn-ext-unprefixed) + +(dnop Dst32RnPrefixedQI "general register QI view" (MACH32 m32c-isa) h-gr-QI f-dst32-rn-prefixed-QI) +(dnop Dst32RnPrefixedHI "general register HI view" (MACH32 m32c-isa) h-gr-HI f-dst32-rn-prefixed-HI) +(dnop Dst32RnPrefixedSI "general register SI view" (MACH32 m32c-isa) h-gr-SI f-dst32-rn-prefixed-SI) + +(dnop Dst16RnQI-S "general register QI view" (MACH16 m16c-isa) h-r0l-r0h f-dst16-rn-QI-s) + +(dnop Dst16AnQI-S "address register QI view" (MACH16 m16c-isa) h-ar-QI f-dst16-rn-QI-s) + +(dnop Bit16Rn "general register bit view" (MACH16 m16c-isa) h-gr-HI f-dst16-rn) + +(dnop Bit32RnPrefixed "general register bit view" (MACH32 m32c-isa) h-gr-QI f-dst32-rn-prefixed-QI) +(dnop Bit32RnUnprefixed "general register bit view" (MACH32 m32c-isa) h-gr-QI f-dst32-rn-unprefixed-QI) + +(dnop R0 "r0" (all-isas) h-r0 f-nil) +(dnop R1 "r1" (all-isas) h-r1 f-nil) +(dnop R2 "r2" (all-isas) h-r2 f-nil) +(dnop R3 "r3" (all-isas) h-r3 f-nil) +(dnop R0l "r0l" (all-isas) h-r0l f-nil) +(dnop R0h "r0h" (all-isas) h-r0h f-nil) +(dnop R2R0 "r2r0" (all-isas) h-r2r0 f-nil) +(dnop R3R1 "r3r1" (all-isas) h-r3r1 f-nil) +(dnop R1R2R0 "r1r2r0" (all-isas) h-r1r2r0 f-nil) + +(dnop Dst16An "address register" (MACH16 m16c-isa) h-ar f-dst16-an) +(dnop Dst16AnQI "address register QI view" (MACH16 m16c-isa) h-ar-QI f-dst16-an) +(dnop Dst16AnHI "address register HI view" (MACH16 m16c-isa) h-ar-HI f-dst16-an) +(dnop Dst16AnSI "address register SI view" (MACH16 m16c-isa) h-ar-SI f-dst16-an) +(dnop Dst16An-S "address register HI view" (MACH16 m16c-isa) h-ar-HI f-dst16-an-s) + +(dnop Dst32AnUnprefixed "address register" (MACH32 m32c-isa) h-ar f-dst32-an-unprefixed) +(dnop Dst32AnUnprefixedQI "address register QI view" (MACH32 m32c-isa) h-ar-QI f-dst32-an-unprefixed) +(dnop Dst32AnUnprefixedHI "address register HI view" (MACH32 m32c-isa) h-ar-HI f-dst32-an-unprefixed) +(dnop Dst32AnUnprefixedSI "address register SI view" (MACH32 m32c-isa) h-ar f-dst32-an-unprefixed) + +(dnop Dst32AnExtUnprefixed "address register" (MACH32 m32c-isa) h-ar f-dst32-an-unprefixed) + +(dnop Dst32AnPrefixed "address register" (MACH32 m32c-isa) h-ar f-dst32-an-prefixed) +(dnop Dst32AnPrefixedQI "address register QI view" (MACH32 m32c-isa) h-ar-QI f-dst32-an-prefixed) +(dnop Dst32AnPrefixedHI "address register HI view" (MACH32 m32c-isa) h-ar-HI f-dst32-an-prefixed) +(dnop Dst32AnPrefixedSI "address register SI view" (MACH32 m32c-isa) h-ar f-dst32-an-prefixed) + +(dnop Bit16An "address register bit view" (MACH16 m16c-isa) h-ar f-dst16-an) + +(dnop Bit32AnPrefixed "address register bit" (MACH32 m32c-isa) h-ar f-dst32-an-prefixed) +(dnop Bit32AnUnprefixed "address register bit" (MACH32 m32c-isa) h-ar f-dst32-an-unprefixed) + +(dnop A0 "a0" (all-isas) h-a0 f-nil) +(dnop A1 "a1" (all-isas) h-a1 f-nil) + +(dnop sb "SB register" (all-isas SEM-ONLY) h-sb f-nil) +(dnop fb "FB register" (all-isas SEM-ONLY) h-fb f-nil) +(dnop sp "SP register" (all-isas SEM-ONLY) h-sp f-nil) + +(define-full-operand SrcDst16-r0l-r0h-S-normal "r0l/r0h pair" (MACH16 m16c-isa) + h-sint DFLT f-5-1 + ((parse "r0l_r0h") (print "r0l_r0h")) () () +) + +(define-full-operand Regsetpop "popm regset" (all-isas) h-uint + DFLT f-8-8 ((parse "pop_regset") (print "pop_regset")) () ()) +(define-full-operand Regsetpush "pushm regset" (all-isas) h-uint + DFLT f-8-8 ((parse "push_regset") (print "push_regset")) () ()) + +(dnop Rn16-push-S "r0[lh]" (MACH16 m16c-isa) h-gr-QI f-4-1) +(dnop An16-push-S "a[01]" (MACH16 m16c-isa) h-ar-HI f-4-1) + +;------------------------------------------------------------- +; Offsets and absolutes +;------------------------------------------------------------- + +(define-full-operand Dsp-8-u6 "unsigned 6 bit displacement at offset 8 bits" (all-isas) + h-uint DFLT f-dsp-8-u6 + ((parse "unsigned6")) () () +) +(define-full-operand Dsp-8-u8 "unsigned 8 bit displacement at offset 8 bits" (all-isas) + h-uint DFLT f-dsp-8-u8 + ((parse "unsigned8")) () () +) +(define-full-operand Dsp-8-u16 "unsigned 16 bit displacement at offset 8 bits" (all-isas) + h-uint DFLT f-dsp-8-u16 + ((parse "unsigned16")) () () +) +(define-full-operand Dsp-8-s8 "signed 8 bit displacement at offset 8 bits" (all-isas) + h-sint DFLT f-dsp-8-s8 + ((parse "signed8")) () () +) +(define-full-operand Dsp-8-s24 "signed 24 bit displacement at offset 8 bits" (all-isas) + h-sint DFLT f-dsp-8-s24 + ((parse "signed24")) () () +) +(define-full-operand Dsp-8-u24 "unsigned 24 bit displacement at offset 8 bits" (all-isas) + h-uint DFLT f-dsp-8-u24 + ((parse "unsigned24")) () () +) +(define-full-operand Dsp-10-u6 "unsigned 6 bit displacement at offset 10 bits" (all-isas) + h-uint DFLT f-dsp-10-u6 + ((parse "unsigned6")) () () +) +(define-full-operand Dsp-16-u8 "unsigned 8 bit displacement at offset 16 bits" (all-isas) + h-uint DFLT f-dsp-16-u8 + ((parse "unsigned8")) () () +) +(define-full-operand Dsp-16-u16 "unsigned 16 bit displacement at offset 16 bits" (all-isas) + h-uint DFLT f-dsp-16-u16 + ((parse "unsigned16")) () () +) +(define-full-operand Dsp-16-u20 "unsigned 20 bit displacement at offset 16 bits" (all-isas) + h-uint DFLT f-dsp-16-u24 + ((parse "unsigned20")) () () +) +(define-full-operand Dsp-16-u24 "unsigned 24 bit displacement at offset 16 bits" (all-isas) + h-uint DFLT f-dsp-16-u24 + ((parse "unsigned24")) () () +) +(define-full-operand Dsp-16-s8 "signed 8 bit displacement at offset 16 bits" (all-isas) + h-sint DFLT f-dsp-16-s8 + ((parse "signed8")) () () +) +(define-full-operand Dsp-16-s16 "signed 16 bit displacement at offset 16 bits" (all-isas) + h-sint DFLT f-dsp-16-s16 + ((parse "signed16")) () () +) +(define-full-operand Dsp-24-u8 "unsigned 8 bit displacement at offset 24 bits" (all-isas) + h-uint DFLT f-dsp-24-u8 + ((parse "unsigned8")) () () +) +(define-full-operand Dsp-24-u16 "unsigned 16 bit displacement at offset 24 bits" (all-isas) + h-uint DFLT f-dsp-24-u16 + ((parse "unsigned16")) () () +) +(define-full-operand Dsp-24-u20 "unsigned 20 bit displacement at offset 24 bits" (all-isas) + h-uint DFLT f-dsp-24-u24 + ((parse "unsigned20")) () () +) +(define-full-operand Dsp-24-u24 "unsigned 24 bit displacement at offset 24 bits" (all-isas) + h-uint DFLT f-dsp-24-u24 + ((parse "unsigned24")) () () +) +(define-full-operand Dsp-24-s8 "signed 8 bit displacement at offset 24 bits" (all-isas) + h-sint DFLT f-dsp-24-s8 + ((parse "signed8")) () () +) +(define-full-operand Dsp-24-s16 "signed 16 bit displacement at offset 24 bits" (all-isas) + h-sint DFLT f-dsp-24-s16 + ((parse "signed16")) () () +) +(define-full-operand Dsp-32-u8 "unsigned 8 bit displacement at offset 32 bits" (all-isas) + h-uint DFLT f-dsp-32-u8 + ((parse "unsigned8")) () () +) +(define-full-operand Dsp-32-u16 "unsigned 16 bit displacement at offset 32 bits" (all-isas) + h-uint DFLT f-dsp-32-u16 + ((parse "unsigned16")) () () +) +(define-full-operand Dsp-32-u24 "unsigned 24 bit displacement at offset 32 bits" (all-isas) + h-uint DFLT f-dsp-32-u24 + ((parse "unsigned24")) () () +) +(define-full-operand Dsp-32-u20 "unsigned 20 bit displacement at offset 32 bits" (all-isas) + h-uint DFLT f-dsp-32-u24 + ((parse "unsigned20")) () () +) +(define-full-operand Dsp-32-s8 "signed 8 bit displacement at offset 32 bits" (all-isas) + h-sint DFLT f-dsp-32-s8 + ((parse "signed8")) () () +) +(define-full-operand Dsp-32-s16 "signed 16 bit displacement at offset 32 bits" (all-isas) + h-sint DFLT f-dsp-32-s16 + ((parse "signed16")) () () +) +(define-full-operand Dsp-40-u8 "unsigned 8 bit displacement at offset 40 bits" (all-isas) + h-uint DFLT f-dsp-40-u8 + ((parse "unsigned8")) () () +) +(define-full-operand Dsp-40-s8 "signed 8 bit displacement at offset 40 bits" (all-isas) + h-sint DFLT f-dsp-40-s8 + ((parse "signed8")) () () +) +(define-full-operand Dsp-40-u16 "unsigned 16 bit displacement at offset 40 bits" (all-isas) + h-uint DFLT f-dsp-40-u16 + ((parse "unsigned16")) () () +) +(define-full-operand Dsp-40-s16 "signed 16 bit displacement at offset 40 bits" (all-isas) + h-sint DFLT f-dsp-40-s16 + ((parse "signed16")) () () +) +(define-full-operand Dsp-40-u20 "unsigned 20 bit displacement at offset 40 bits" (all-isas) + h-uint DFLT f-dsp-40-u20 + ((parse "unsigned20")) () () +) +(define-full-operand Dsp-40-u24 "unsigned 24 bit displacement at offset 40 bits" (all-isas) + h-uint DFLT f-dsp-40-u24 + ((parse "unsigned24")) () () +) +(define-full-operand Dsp-48-u8 "unsigned 8 bit displacement at offset 48 bits" (all-isas) + h-uint DFLT f-dsp-48-u8 + ((parse "unsigned8")) () () +) +(define-full-operand Dsp-48-s8 "signed 8 bit displacement at offset 48 bits" (all-isas) + h-sint DFLT f-dsp-48-s8 + ((parse "signed8")) () () +) +(define-full-operand Dsp-48-u16 "unsigned 16 bit displacement at offset 48 bits" (all-isas) + h-uint DFLT f-dsp-48-u16 + ((parse "unsigned16")) () () +) +(define-full-operand Dsp-48-s16 "signed 16 bit displacement at offset 48 bits" (all-isas) + h-sint DFLT f-dsp-48-s16 + ((parse "signed16")) () () +) +(define-full-operand Dsp-48-u20 "unsigned 24 bit displacement at offset 40 bits" (all-isas) + h-uint DFLT f-dsp-48-u20 + ((parse "unsigned24")) () () +) +(define-full-operand Dsp-48-u24 "unsigned 24 bit displacement at offset 48 bits" (all-isas) + h-uint DFLT f-dsp-48-u24 + ((parse "unsigned24")) () () +) + +(define-full-operand Imm-8-s4 "signed 4 bit immediate at offset 8 bits" (all-isas) + h-sint DFLT f-imm-8-s4 + ((parse "signed4")) () () +) +(define-full-operand Imm-8-s4n "negated 4 bit immediate at offset 8 bits" (all-isas) + h-sint DFLT f-imm-8-s4 + ((parse "signed4n") (print "signed4n")) () () +) +(define-full-operand Imm-sh-8-s4 "signed 4 bit shift immediate at offset 8 bits" (all-isas) + h-shimm DFLT f-imm-8-s4 + () () () +) +(define-full-operand Imm-8-QI "signed 8 bit immediate at offset 8 bits" (all-isas) + h-sint DFLT f-dsp-8-s8 + ((parse "signed8")) () () +) +(define-full-operand Imm-8-HI "signed 16 bit immediate at offset 8 bits" (all-isas) + h-sint DFLT f-dsp-8-s16 + ((parse "signed16")) () () +) +(define-full-operand Imm-12-s4 "signed 4 bit immediate at offset 12 bits" (all-isas) + h-sint DFLT f-imm-12-s4 + ((parse "signed4")) () () +) +(define-full-operand Imm-12-s4n "negated 4 bit immediate at offset 12 bits" (all-isas) + h-sint DFLT f-imm-12-s4 + ((parse "signed4n") (print "signed4n")) () () +) +(define-full-operand Imm-sh-12-s4 "signed 4 bit shift immediate at offset 12 bits" (all-isas) + h-shimm DFLT f-imm-12-s4 + () () () +) +(define-full-operand Imm-13-u3 "signed 3 bit immediate at offset 13 bits" (all-isas) + h-sint DFLT f-imm-13-u3 + ((parse "signed4")) () () +) +(define-full-operand Imm-20-s4 "signed 4 bit immediate at offset 20 bits" (all-isas) + h-sint DFLT f-imm-20-s4 + ((parse "signed4")) () () +) +(define-full-operand Imm-sh-20-s4 "signed 4 bit shift immediate at offset 12 bits" (all-isas) + h-shimm DFLT f-imm-20-s4 + () () () +) +(define-full-operand Imm-16-QI "signed 8 bit immediate at offset 16 bits" (all-isas) + h-sint DFLT f-dsp-16-s8 + ((parse "signed8")) () () +) +(define-full-operand Imm-16-HI "signed 16 bit immediate at offset 16 bits" (all-isas) + h-sint DFLT f-dsp-16-s16 + ((parse "signed16")) () () +) +(define-full-operand Imm-16-SI "signed 32 bit immediate at offset 16 bits" (all-isas) + h-sint DFLT f-dsp-16-s32 + ((parse "signed32")) () () +) +(define-full-operand Imm-24-QI "signed 8 bit immediate at offset 24 bits" (all-isas) + h-sint DFLT f-dsp-24-s8 + ((parse "signed8")) () () +) +(define-full-operand Imm-24-HI "signed 16 bit immediate at offset 24 bits" (all-isas) + h-sint DFLT f-dsp-24-s16 + ((parse "signed16")) () () +) +(define-full-operand Imm-24-SI "signed 32 bit immediate at offset 24 bits" (all-isas) + h-sint DFLT f-dsp-24-s32 + ((parse "signed32")) () () +) +(define-full-operand Imm-32-QI "signed 8 bit immediate at offset 32 bits" (all-isas) + h-sint DFLT f-dsp-32-s8 + ((parse "signed8")) () () +) +(define-full-operand Imm-32-SI "signed 32 bit immediate at offset 32 bits" (all-isas) + h-sint DFLT f-dsp-32-s32 + ((parse "signed32")) () () +) +(define-full-operand Imm-32-HI "signed 16 bit immediate at offset 32 bits" (all-isas) + h-sint DFLT f-dsp-32-s16 + ((parse "signed16")) () () +) +(define-full-operand Imm-40-QI "signed 8 bit immediate at offset 40 bits" (all-isas) + h-sint DFLT f-dsp-40-s8 + ((parse "signed8")) () () +) +(define-full-operand Imm-40-HI "signed 16 bit immediate at offset 40 bits" (all-isas) + h-sint DFLT f-dsp-40-s16 + ((parse "signed16")) () () +) +(define-full-operand Imm-40-SI "signed 32 bit immediate at offset 40 bits" (all-isas) + h-sint DFLT f-dsp-40-s32 + ((parse "signed32")) () () +) +(define-full-operand Imm-48-QI "signed 8 bit immediate at offset 48 bits" (all-isas) + h-sint DFLT f-dsp-48-s8 + ((parse "signed8")) () () +) +(define-full-operand Imm-48-HI "signed 16 bit immediate at offset 48 bits" (all-isas) + h-sint DFLT f-dsp-48-s16 + ((parse "signed16")) () () +) +(define-full-operand Imm-48-SI "signed 32 bit immediate at offset 48 bits" (all-isas) + h-sint DFLT f-dsp-48-s32 + ((parse "signed32")) () () +) +(define-full-operand Imm-56-QI "signed 8 bit immediate at offset 56 bits" (all-isas) + h-sint DFLT f-dsp-56-s8 + ((parse "signed8")) () () +) +(define-full-operand Imm-56-HI "signed 16 bit immediate at offset 56 bits" (all-isas) + h-sint DFLT f-dsp-56-s16 + ((parse "signed16")) () () +) +(define-full-operand Imm-64-HI "signed 16 bit immediate at offset 64 bits" (all-isas) + h-sint DFLT f-dsp-64-s16 + ((parse "signed16")) () () +) +(define-full-operand Imm1-S "signed 1 bit immediate for short format binary insns" (m32c-isa) + h-sint DFLT f-imm1-S + ((parse "imm1_S")) () () +) +(define-full-operand Imm3-S "signed 3 bit immediate for short format binary insns" (m32c-isa) + h-sint DFLT f-imm3-S + ((parse "imm3_S")) () () +) +(define-full-operand Bit3-S "3 bit bit number" (m32c-isa) + h-sint DFLT f-imm3-S + ((parse "bit3_S")) () () +) + +;------------------------------------------------------------- +; Bit numbers +;------------------------------------------------------------- + +(define-full-operand Bitno16R "bit number for indexing registers" (m16c-isa) + h-uint DFLT f-dsp-16-u8 + ((parse "Bitno16R")) () () +) +(dnop Bitno32Prefixed "bit number for indexing objects" (m32c-isa) h-uint f-bitno32-prefixed) +(dnop Bitno32Unprefixed "bit number for indexing objects" (m32c-isa) h-uint f-bitno32-unprefixed) + +(define-full-operand BitBase16-16-u8 "unsigned bit,base:8 at offset 16for m16c" (m16c-isa) + h-uint DFLT f-dsp-16-u8 + ((parse "unsigned_bitbase8") (print "unsigned_bitbase")) () () +) +(define-full-operand BitBase16-16-s8 "signed bit,base:8 at offset 16for m16c" (m16c-isa) + h-sint DFLT f-dsp-16-s8 + ((parse "signed_bitbase8") (print "signed_bitbase")) () () +) +(define-full-operand BitBase16-16-u16 "unsigned bit,base:16 at offset 16 for m16c" (m16c-isa) + h-uint DFLT f-dsp-16-u16 + ((parse "unsigned_bitbase16") (print "unsigned_bitbase")) () () +) +(define-full-operand BitBase16-8-u11-S "signed bit,base:11 at offset 16 for m16c" (m16c-isa) + h-uint DFLT f-bitbase16-u11-S + ((parse "unsigned_bitbase11") (print "unsigned_bitbase")) () () +) + +(define-full-operand BitBase32-16-u11-Unprefixed "unsigned bit,base:11 at offset 16 for m32c" (m32c-isa) + h-uint DFLT f-bitbase32-16-u11-unprefixed + ((parse "unsigned_bitbase11") (print "unsigned_bitbase")) () () +) +(define-full-operand BitBase32-16-s11-Unprefixed "signed bit,base:11 at offset 16 for m32c" (m32c-isa) + h-sint DFLT f-bitbase32-16-s11-unprefixed + ((parse "signed_bitbase11") (print "signed_bitbase")) () () +) +(define-full-operand BitBase32-16-u19-Unprefixed "unsigned bit,base:19 at offset 16 for m32c" (m32c-isa) + h-uint DFLT f-bitbase32-16-u19-unprefixed + ((parse "unsigned_bitbase19") (print "unsigned_bitbase")) () () +) +(define-full-operand BitBase32-16-s19-Unprefixed "signed bit,base:19 at offset 16 for m32c" (m32c-isa) + h-sint DFLT f-bitbase32-16-s19-unprefixed + ((parse "signed_bitbase19") (print "signed_bitbase")) () () +) +(define-full-operand BitBase32-16-u27-Unprefixed "unsigned bit,base:27 at offset 16 for m32c" (m32c-isa) + h-uint DFLT f-bitbase32-16-u27-unprefixed + ((parse "unsigned_bitbase27") (print "unsigned_bitbase")) () () +) +(define-full-operand BitBase32-24-u11-Prefixed "unsigned bit,base:11 at offset 24 for m32c" (m32c-isa) + h-uint DFLT f-bitbase32-24-u11-prefixed + ((parse "unsigned_bitbase11") (print "unsigned_bitbase")) () () +) +(define-full-operand BitBase32-24-s11-Prefixed "signed bit,base:11 at offset 24 for m32c" (m32c-isa) + h-sint DFLT f-bitbase32-24-s11-prefixed + ((parse "signed_bitbase11") (print "signed_bitbase")) () () +) +(define-full-operand BitBase32-24-u19-Prefixed "unsigned bit,base:19 at offset 24 for m32c" (m32c-isa) + h-uint DFLT f-bitbase32-24-u19-prefixed + ((parse "unsigned_bitbase19") (print "unsigned_bitbase")) () () +) +(define-full-operand BitBase32-24-s19-Prefixed "signed bit,base:19 at offset 24 for m32c" (m32c-isa) + h-sint DFLT f-bitbase32-24-s19-prefixed + ((parse "signed_bitbase19") (print "signed_bitbase")) () () +) +(define-full-operand BitBase32-24-u27-Prefixed "unsigned bit,base:27 at offset 24 for m32c" (m32c-isa) + h-uint DFLT f-bitbase32-24-u27-prefixed + ((parse "unsigned_bitbase27") (print "unsigned_bitbase")) () () +) +;------------------------------------------------------------- +; Labels +;------------------------------------------------------------- + +(define-full-operand Lab-5-3 "3 bit label" (all-isas RELAX) + h-iaddr DFLT f-lab-5-3 + ((parse "lab_5_3")) () () ) + +(define-full-operand Lab32-jmp-s "3 bit label" (all-isas RELAX) + h-iaddr DFLT f-lab32-jmp-s + ((parse "lab_5_3")) () () ) + +(dnop Lab-8-8 "8 bit label" (all-isas RELAX) h-iaddr f-lab-8-8) +(dnop Lab-8-16 "16 bit label" (all-isas RELAX) h-iaddr f-lab-8-16) +(dnop Lab-8-24 "24 bit label" (all-isas RELAX) h-iaddr f-lab-8-24) +(dnop Lab-16-8 "8 bit label" (all-isas RELAX) h-iaddr f-lab-16-8) +(dnop Lab-24-8 "8 bit label" (all-isas RELAX) h-iaddr f-lab-24-8) +(dnop Lab-32-8 "8 bit label" (all-isas RELAX) h-iaddr f-lab-32-8) +(dnop Lab-40-8 "8 bit label" (all-isas RELAX) h-iaddr f-lab-40-8) + +;------------------------------------------------------------- +; Condition code bits +;------------------------------------------------------------- + +(dnop sbit "negative bit" (SEM-ONLY all-isas) h-sbit f-nil) +(dnop obit "overflow bit" (SEM-ONLY all-isas) h-obit f-nil) +(dnop zbit "zero bit" (SEM-ONLY all-isas) h-zbit f-nil) +(dnop cbit "carry bit" (SEM-ONLY all-isas) h-cbit f-nil) +(dnop ubit "stack ptr select bit" (SEM-ONLY all-isas) h-ubit f-nil) +(dnop ibit "interrupt enable bit" (SEM-ONLY all-isas) h-ibit f-nil) +(dnop bbit "reg bank select bit" (SEM-ONLY all-isas) h-bbit f-nil) +(dnop dbit "debug bit" (SEM-ONLY all-isas) h-dbit f-nil) + +;------------------------------------------------------------- +; Condition operands +;------------------------------------------------------------- + +(define-pmacro (cond-operand mach offset) + (dnop (.sym cond mach - offset) "condition" ((.sym m mach c-isa)) (.sym h-cond mach) (.sym f-dsp- offset -u8)) +) + +(cond-operand 16 16) +(cond-operand 16 24) +(cond-operand 16 32) +(cond-operand 32 16) +(cond-operand 32 24) +(cond-operand 32 32) +(cond-operand 32 40) + +(dnop cond16c "condition" (m16c-isa) h-cond16c f-cond16) +(dnop cond16j "condition" (m16c-isa) h-cond16j f-cond16) +(dnop cond16j5 "condition" (m16c-isa) h-cond16j-5 f-cond16j-5) +(dnop cond32 "condition" (m32c-isa) h-cond32 f-cond32) +(dnop cond32j "condition" (m32c-isa) h-cond32 f-cond32j) +(dnop sccond32 "scCND condition" (m32c-isa) h-cond32 f-cond16) +(dnop flags16 "flags" (m16c-isa) h-flags f-9-3) +(dnop flags32 "flags" (m32c-isa) h-flags f-13-3) +(dnop cr16 "control" (m16c-isa) h-cr-16 f-9-3) +(dnop cr1-Unprefixed-32 "control" (m32c-isa) h-cr1-32 f-13-3) +(dnop cr1-Prefixed-32 "control" (m32c-isa) h-cr1-32 f-21-3) +(dnop cr2-32 "control" (m32c-isa) h-cr2-32 f-13-3) +(dnop cr3-Unprefixed-32 "control" (m32c-isa) h-cr3-32 f-13-3) +(dnop cr3-Prefixed-32 "control" (m32c-isa) h-cr3-32 f-21-3) + +;------------------------------------------------------------- +; Suffixes +;------------------------------------------------------------- + +(define-full-operand Z "Suffix for zero format insns" (all-isas) + h-sint DFLT f-nil + ((parse "Z") (print "Z")) () () +) +(define-full-operand S "Suffix for short format insns" (all-isas) + h-sint DFLT f-nil + ((parse "S") (print "S")) () () +) +(define-full-operand Q "Suffix for quick format insns" (all-isas) + h-sint DFLT f-nil + ((parse "Q") (print "Q")) () () +) +(define-full-operand G "Suffix for general format insns" (all-isas) + h-sint DFLT f-nil + ((parse "G") (print "G")) () () +) +(define-full-operand X "Empty suffix" (all-isas) + h-sint DFLT f-nil + ((parse "X") (print "X")) () () +) +(define-full-operand size "any size specifier" (all-isas) + h-sint DFLT f-nil + ((parse "size") (print "size")) () () +) +;------------------------------------------------------------- +; Misc +;------------------------------------------------------------- + +(dnop BitIndex "Bit Index for the next insn" (SEM-ONLY MACH32 m32c-isa) h-bit-index f-nil) +(dnop SrcIndex "Source Index for the next insn" (SEM-ONLY MACH32 m32c-isa) h-src-index f-nil) +(dnop DstIndex "Destination Index for the next insn" (SEM-ONLY MACH32 m32c-isa) h-dst-index f-nil) +(dnop NoRemainder "Place holder for when the remainder is not kept" (SEM-ONLY MACH32 m32c-isa) h-none f-nil) + +;============================================================= +; Derived Operands + +; Memory reference macros that clip addresses appropriately. Refer to +; memory at ADDRESS in MODE, clipped appropriately for either the m16c +; or m32c. +(define-pmacro (mem16 mode address) + (mem mode (and #xffff address))) + +(define-pmacro (mem20 mode address) + (mem mode (and #xfffff address))) + +(define-pmacro (mem32 mode address) + (mem mode (and #xffffff address))) + +; Like mem16 and mem32, but takes MACH as a parameter. MACH must be +; either 16 or 32. +(define-pmacro (mem-mach mach mode address) + ((.sym mem mach) mode address)) + +;------------------------------------------------------------- +; Source +;------------------------------------------------------------- +; Rn direct +;------------------------------------------------------------- + +(define-pmacro (src16-Rn-direct-operand xmode) + (begin + (define-derived-operand + (name (.sym src16-Rn-direct- xmode)) + (comment (.str "m16c Rn direct source " xmode)) + (attrs (machine 16)) + (mode xmode) + (args ((.sym Src16Rn xmode))) + (syntax (.str "$Src16Rn" xmode)) + (base-ifield f-8-4) + (encoding (+ (f-8-2 0) (.sym Src16Rn xmode))) + (ifield-assertion (eq f-8-2 0)) + (getter (trunc xmode (.sym Src16Rn xmode))) + (setter (set (.sym Src16Rn xmode) newval)) + ) + ) +) +(src16-Rn-direct-operand QI) +(src16-Rn-direct-operand HI) + +(define-pmacro (src32-Rn-direct-operand group base xmode) + (begin + (define-derived-operand + (name (.sym src32-Rn-direct- group - xmode)) + (comment (.str "m32c Rn direct source " xmode)) + (attrs (machine 32)) + (mode xmode) + (args ((.sym Src32Rn group xmode))) + (syntax (.str "$Src32Rn" group xmode)) + (base-ifield (.sym f- base -11)) + (encoding (+ ((.sym f- base -3) 4) (.sym Src32Rn group xmode))) + (ifield-assertion (eq (.sym f- base -3) 4)) + (getter (trunc xmode (.sym Src32Rn group xmode))) + (setter (set (.sym Src32Rn group xmode) newval)) + ) + ) +) + +(src32-Rn-direct-operand Unprefixed 1 QI) +(src32-Rn-direct-operand Prefixed 9 QI) +(src32-Rn-direct-operand Unprefixed 1 HI) +(src32-Rn-direct-operand Prefixed 9 HI) +(src32-Rn-direct-operand Unprefixed 1 SI) +(src32-Rn-direct-operand Prefixed 9 SI) + +;------------------------------------------------------------- +; An direct +;------------------------------------------------------------- + +(define-pmacro (src16-An-direct-operand xmode) + (begin + (define-derived-operand + (name (.sym src16-An-direct- xmode)) + (comment (.str "m16c An direct destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args ((.sym Src16An xmode))) + (syntax (.str "$Src16An" xmode)) + (base-ifield f-8-4) + (encoding (+ (f-8-2 1) (f-10-1 0) (.sym Src16An xmode))) + (ifield-assertion (andif (eq f-8-2 1) (eq f-10-1 0))) + (getter (trunc xmode (.sym Src16An xmode))) + (setter (set (.sym Src16An xmode) newval)) + ) + ) +) +(src16-An-direct-operand QI) +(src16-An-direct-operand HI) + +(define-pmacro (src32-An-direct-operand group base1 base2 xmode) + (begin + (define-derived-operand + (name (.sym src32-An-direct- group - xmode)) + (comment (.str "m32c An direct destination " xmode)) + (attrs (machine 32)) + (mode xmode) + (args ((.sym Src32An group xmode))) + (syntax (.str "$Src32An" group xmode)) + (base-ifield (.sym f- base1 -11)) + (encoding (+ ((.sym f- base1 -3) 0) ((.sym f- base2 -1) 1) (.sym Src32An group xmode))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 0) (eq (.sym f- base2 -1) 1))) + (getter (trunc xmode (.sym Src32An group xmode))) + (setter (set (.sym Src32An group xmode) newval)) + ) + ) +) + +(src32-An-direct-operand Unprefixed 1 10 QI) +(src32-An-direct-operand Unprefixed 1 10 HI) +(src32-An-direct-operand Unprefixed 1 10 SI) +(src32-An-direct-operand Prefixed 9 18 QI) +(src32-An-direct-operand Prefixed 9 18 HI) +(src32-An-direct-operand Prefixed 9 18 SI) + +;------------------------------------------------------------- +; An indirect +;------------------------------------------------------------- + +(define-pmacro (src16-An-indirect-operand xmode) + (begin + (define-derived-operand + (name (.sym src16-An-indirect- xmode)) + (comment (.str "m16c An indirect destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args (Src16An)) + (syntax "[$Src16An]") + (base-ifield f-8-4) + (encoding (+ (f-8-2 1) (f-10-1 1) Src16An)) + (ifield-assertion (andif (eq f-8-2 1) (eq f-10-1 1))) + (getter (mem16 xmode Src16An)) + (setter (set (mem16 xmode Src16An) newval)) + ) + ) +) +(src16-An-indirect-operand QI) +(src16-An-indirect-operand HI) + +(define-pmacro (src32-An-indirect-operand group base1 base2 xmode) + (begin + (define-derived-operand + (name (.sym src32-An-indirect- group - xmode)) + (comment (.str "m32c An indirect destination " xmode)) + (attrs (machine 32)) + (mode xmode) + (args ((.sym Src32An group))) + (syntax (.str "[$Src32An" group "]")) + (base-ifield (.sym f- base1 -11)) + (encoding (+ ((.sym f- base1 -3) 0) ((.sym f- base2 -1) 0) (.sym Src32An group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 0) (eq (.sym f- base2 -1) 0))) + (getter (c-call xmode (.str "operand_getter_" xmode) (.sym Src32An group) + (const 0))) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval + (.sym Src32An group) (const 0))) +; (getter (mem32 xmode (.sym Src32An group))) +; (setter (set (mem32 xmode (.sym Src32An group)) newval)) + ) + ) +) + +(src32-An-indirect-operand Unprefixed 1 10 QI) +(src32-An-indirect-operand Unprefixed 1 10 HI) +(src32-An-indirect-operand Unprefixed 1 10 SI) +(src32-An-indirect-operand Prefixed 9 18 QI) +(src32-An-indirect-operand Prefixed 9 18 HI) +(src32-An-indirect-operand Prefixed 9 18 SI) + +;------------------------------------------------------------- +; dsp:d[r] relative +;------------------------------------------------------------- + +(define-pmacro (src16-relative-operand xmode) + (begin + (define-derived-operand + (name (.sym src16-16-8-SB-relative- xmode)) + (comment (.str "m16c dsp:8[sb] relative destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args (Dsp-16-u8)) + (syntax "${Dsp-16-u8}[sb]") + (base-ifield f-8-4) + (encoding (+ (f-8-4 #xA) Dsp-16-u8)) + (ifield-assertion (eq f-8-4 #xA)) + (getter (mem16 xmode (add Dsp-16-u8 (reg h-sb)))) + (setter (set (mem16 xmode (add Dsp-16-u8 (reg h-sb))) newval)) + ) + (define-derived-operand + (name (.sym src16-16-16-SB-relative- xmode)) + (comment (.str "m16c dsp:16[sb] relative destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args (Dsp-16-u16)) + (syntax "${Dsp-16-u16}[sb]") + (base-ifield f-8-4) + (encoding (+ (f-8-4 #xE) Dsp-16-u16)) + (ifield-assertion (eq f-8-4 #xE)) + (getter (mem16 xmode (add Dsp-16-u16 (reg h-sb)))) + (setter (set (mem16 xmode (add Dsp-16-u16 (reg h-sb))) newval)) + ) + (define-derived-operand + (name (.sym src16-16-8-FB-relative- xmode)) + (comment (.str "m16c dsp:8[fb] relative destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args (Dsp-16-s8)) + (syntax "${Dsp-16-s8}[fb]") + (base-ifield f-8-4) + (encoding (+ (f-8-4 #xB) Dsp-16-s8)) + (ifield-assertion (eq f-8-4 #xB)) + (getter (mem16 xmode (add Dsp-16-s8 (reg h-fb)))) + (setter (set (mem16 xmode (add Dsp-16-s8 (reg h-fb))) newval)) + ) + (define-derived-operand + (name (.sym src16-16-8-An-relative- xmode)) + (comment (.str "m16c dsp:8[An] relative destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args (Src16An Dsp-16-u8)) + (syntax "${Dsp-16-u8}[$Src16An]") + (base-ifield f-8-4) + (encoding (+ (f-8-2 2) (f-10-1 0) Dsp-16-u8 Src16An)) + (ifield-assertion (andif (eq f-8-2 2) (eq f-10-1 0))) + (getter (mem16 xmode (add Dsp-16-u8 Src16An))) + (setter (set (mem16 xmode (add Dsp-16-u8 Src16An)) newval)) + ) + (define-derived-operand + (name (.sym src16-16-16-An-relative- xmode)) + (comment (.str "m16c dsp:16[An] relative destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args (Src16An Dsp-16-u16)) + (syntax "${Dsp-16-u16}[$Src16An]") + (base-ifield f-8-4) + (encoding (+ (f-8-2 3) (f-10-1 0) Dsp-16-u16 Src16An)) + (ifield-assertion (andif (eq f-8-2 3) (eq f-10-1 0))) + (getter (mem16 xmode (add Dsp-16-u16 Src16An))) + (setter (set (mem16 xmode (add Dsp-16-u16 Src16An)) newval)) + ) + (define-derived-operand + (name (.sym src16-16-20-An-relative- xmode)) + (comment (.str "m16c dsp:20[An] relative destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args (Src16An Dsp-16-u20)) + (syntax "${Dsp-16-u20}[$Src16An]") + (base-ifield f-8-4) + (encoding (+ (f-8-2 3) (f-10-1 0) Dsp-16-u20 Src16An)) + (ifield-assertion (andif (eq f-8-2 3) (eq f-10-1 0))) + (getter (mem20 xmode (add Dsp-16-u20 Src16An))) + (setter (set (mem20 xmode (add Dsp-16-u20 Src16An)) newval)) + ) + ) +) + +(src16-relative-operand QI) +(src16-relative-operand HI) + +(define-pmacro (src32-relative-operand offset group base1 base2 xmode) + (begin + (define-derived-operand + (name (.sym src32- offset -8-SB-relative- group - xmode)) + (comment (.str "m32c dsp:8[sb] relative destination " xmode)) + (attrs (machine 32)) + (mode xmode) + (args ((.sym Dsp- offset -u8))) + (syntax (.str "${Dsp-" offset "-u8}[sb]")) + (base-ifield (.sym f- base1 -11)) + (encoding (+ ((.sym f- base1 -3) 1) ((.sym f- base2 -2) 2) (.sym Dsp- offset -u8))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 1) (eq (.sym f- base2 -2) 2))) + (getter (c-call xmode (.str "operand_getter_" xmode) sb (.sym Dsp- offset -u8))) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval sb (.sym Dsp- offset -u8))) +; (getter (mem32 xmode (add (.sym Dsp- offset -u8) (reg h-sb)))) +; (setter (set (mem32 xmode (add (.sym Dsp- offset -u8) (reg h-sb))) newval)) + ) + (define-derived-operand + (name (.sym src32- offset -16-SB-relative- group - xmode)) + (comment (.str "m32c dsp:16[sb] relative destination " xmode)) + (attrs (machine 32)) + (mode xmode) + (args ((.sym Dsp- offset -u16))) + (syntax (.str "${Dsp-" offset "-u16}[sb]")) + (base-ifield (.sym f- base1 -11)) + (encoding (+ ((.sym f- base1 -3) 2) ((.sym f- base2 -2) 2) (.sym Dsp- offset -u16))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 2) (eq (.sym f- base2 -2) 2))) + (getter (c-call xmode (.str "operand_getter_" xmode) sb (.sym Dsp- offset -u16))) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval sb (.sym Dsp- offset -u16))) +; (getter (mem32 xmode (add (.sym Dsp- offset -u16) (reg h-sb)))) +; (setter (set (mem32 xmode (add (.sym Dsp- offset -u16) (reg h-sb))) newval)) + ) + (define-derived-operand + (name (.sym src32- offset -8-FB-relative- group - xmode)) + (comment (.str "m32c dsp:8[fb] relative destination " xmode)) + (attrs (machine 32)) + (mode xmode) + (args ((.sym Dsp- offset -s8))) + (syntax (.str "${Dsp-" offset "-s8}[fb]")) + (base-ifield (.sym f- base1 -11)) + (encoding (+ ((.sym f- base1 -3) 1) ((.sym f- base2 -2) 3) (.sym Dsp- offset -s8))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 1) (eq (.sym f- base2 -2) 3))) + (getter (c-call xmode (.str "operand_getter_" xmode) fb (.sym Dsp- offset -s8))) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval fb (.sym Dsp- offset -s8))) +; (getter (mem32 xmode (add (.sym Dsp- offset -s8) (reg h-fb)))) +; (setter (set (mem32 xmode (add (.sym Dsp- offset -s8) (reg h-fb))) newval)) + ) + (define-derived-operand + (name (.sym src32- offset -16-FB-relative- group - xmode)) + (comment (.str "m32c dsp:16[fb] relative destination " xmode)) + (attrs (machine 32)) + (mode xmode) + (args ((.sym Dsp- offset -s16))) + (syntax (.str "${Dsp-" offset "-s16}[fb]")) + (base-ifield (.sym f- base1 -11)) + (encoding (+ ((.sym f- base1 -3) 2) ((.sym f- base2 -2) 3) (.sym Dsp- offset -s16))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 2) (eq (.sym f- base2 -2) 3))) + (getter (c-call xmode (.str "operand_getter_" xmode) fb (.sym Dsp- offset -s16))) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval fb (.sym Dsp- offset -s16))) +; (getter (mem32 xmode (add (.sym Dsp- offset -s16) (reg h-fb)))) +; (setter (set (mem32 xmode (add (.sym Dsp- offset -s16) (reg h-fb))) newval)) + ) + (define-derived-operand + (name (.sym src32- offset -8-An-relative- group - xmode)) + (comment (.str "m32c dsp:8[An] relative destination " xmode)) + (attrs (machine 32)) + (mode xmode) + (args ((.sym Src32An group) (.sym Dsp- offset -u8))) + (syntax (.str "${Dsp-" offset "-u8}[$Src32An" group "]")) + (base-ifield (.sym f- base1 -11)) + (encoding (+ ((.sym f- base1 -3) 1) ((.sym f- base2 -1) 0) (.sym Dsp- offset -u8) (.sym Src32An group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 1) (eq (.sym f- base2 -1) 0))) + (getter (c-call xmode (.str "operand_getter_" xmode) (.sym Src32An group) (.sym Dsp- offset -u8))) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval (.sym Src32An group) (.sym Dsp- offset -u8))) +; (getter (mem32 xmode (add (.sym Dsp- offset -u8) (.sym Src32An group)))) +; (setter (set (mem32 xmode (add (.sym Dsp- offset -u8) (.sym Src32An group))) newval)) + ) + (define-derived-operand + (name (.sym src32- offset -16-An-relative- group - xmode)) + (comment (.str "m32c dsp:16[An] relative destination " xmode)) + (attrs (machine 32)) + (mode xmode) + (args ((.sym Src32An group) (.sym Dsp- offset -u16))) + (syntax (.str "${Dsp-" offset "-u16}[$Src32An" group "]")) + (base-ifield (.sym f- base1 -11)) + (encoding (+ ((.sym f- base1 -3) 2) ((.sym f- base2 -1) 0) (.sym Dsp- offset -u16) (.sym Src32An group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 2) (eq (.sym f- base2 -1) 0))) + (getter (c-call xmode (.str "operand_getter_" xmode) (.sym Src32An group) (.sym Dsp- offset -u16))) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval (.sym Src32An group) (.sym Dsp- offset -u16))) +; (getter (mem32 xmode (add (.sym Dsp- offset -u16) (.sym Src32An group)))) +; (setter (set (mem32 xmode (add (.sym Dsp- offset -u16) (.sym Src32An group))) newval)) + ) + (define-derived-operand + (name (.sym src32- offset -24-An-relative- group - xmode)) + (comment (.str "m32c dsp:16[An] relative destination " xmode)) + (attrs (machine 32)) + (mode xmode) + (args ((.sym Src32An group) (.sym Dsp- offset -u24))) + (syntax (.str "${Dsp-" offset "-u24}[$Src32An" group "]")) + (base-ifield (.sym f- base1 -11)) + (encoding (+ ((.sym f- base1 -3) 3) ((.sym f- base2 -1) 0) (.sym Dsp- offset -u24) (.sym Src32An group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 3) (eq (.sym f- base2 -1) 0))) + (getter (c-call xmode (.str "operand_getter_" xmode) (.sym Src32An group) (.sym Dsp- offset -u24) )) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval (.sym Src32An group) (.sym Dsp- offset -u24))) +; (getter (mem32 xmode (add (.sym Dsp- offset -u24) (.sym Src32An group)))) +; (setter (set (mem32 xmode (add (.sym Dsp- offset -u24) (.sym Src32An group))) newval)) + ) + ) +) + +(src32-relative-operand 16 Unprefixed 1 10 QI) +(src32-relative-operand 16 Unprefixed 1 10 HI) +(src32-relative-operand 16 Unprefixed 1 10 SI) +(src32-relative-operand 24 Prefixed 9 18 QI) +(src32-relative-operand 24 Prefixed 9 18 HI) +(src32-relative-operand 24 Prefixed 9 18 SI) + +;------------------------------------------------------------- +; Absolute address +;------------------------------------------------------------- + +(define-pmacro (src16-absolute xmode) + (begin + (define-derived-operand + (name (.sym src16-16-16-absolute- xmode)) + (comment (.str "m16c absolute address " xmode)) + (attrs (machine 16)) + (mode xmode) + (args (Dsp-16-u16)) + (syntax (.str "${Dsp-16-u16}")) + (base-ifield f-8-4) + (encoding (+ (f-8-4 #xF) Dsp-16-u16)) + (ifield-assertion (eq f-8-4 #xF)) + (getter (mem16 xmode Dsp-16-u16)) + (setter (set (mem16 xmode Dsp-16-u16) newval)) + ) + ) +) + +(src16-absolute QI) +(src16-absolute HI) + +(define-pmacro (src32-absolute offset group base1 base2 xmode) + (begin + (define-derived-operand + (name (.sym src32- offset -16-absolute- group - xmode)) + (comment (.str "m32c absolute address " xmode)) + (attrs (machine 32)) + (mode xmode) + (args ((.sym Dsp- offset -u16))) + (syntax (.str "${Dsp-" offset "-u16}")) + (base-ifield (.sym f- base1 -11)) + (encoding (+ ((.sym f- base1 -3) 3) ((.sym f- base2 -2) 3) (.sym Dsp- offset -u16))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 3) (eq (.sym f- base2 -2) 3))) + (getter (c-call xmode (.str "operand_getter_" xmode) (const 0) (.sym Dsp- offset -u16))) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval (const 0) (.sym Dsp- offset -u16))) +; (getter (mem32 xmode (.sym Dsp- offset -u16))) +; (setter (set (mem32 xmode (.sym Dsp- offset -u16)) newval)) + ) + (define-derived-operand + (name (.sym src32- offset -24-absolute- group - xmode)) + (comment (.str "m32c absolute address " xmode)) + (attrs (machine 32)) + (mode xmode) + (args ((.sym Dsp- offset -u24))) + (syntax (.str "${Dsp-" offset "-u24}")) + (base-ifield (.sym f- base1 -11)) + (encoding (+ ((.sym f- base1 -3) 3) ((.sym f- base2 -2) 2) (.sym Dsp- offset -u24))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 3) (eq (.sym f- base2 -2) 2))) + (getter (c-call xmode (.str "operand_getter_" xmode) (const 0) (.sym Dsp- offset -u24))) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval (const 0) (.sym Dsp- offset -u24))) +; (getter (mem32 xmode (.sym Dsp- offset -u24))) +; (setter (set (mem32 xmode (.sym Dsp- offset -u24)) newval)) + ) + ) +) + +(src32-absolute 16 Unprefixed 1 10 QI) +(src32-absolute 16 Unprefixed 1 10 HI) +(src32-absolute 16 Unprefixed 1 10 SI) +(src32-absolute 24 Prefixed 9 18 QI) +(src32-absolute 24 Prefixed 9 18 HI) +(src32-absolute 24 Prefixed 9 18 SI) + +;------------------------------------------------------------- +; An indirect indirect +; +; Double indirect addressing uses the lower 3 bytes of the value stored +; at the address referenced by 'op' as the effective address. +;------------------------------------------------------------- + +(define-pmacro (indirect-addr op) (and USI (mem32 USI op) #x00ffffff)) + +; (define-pmacro (src-An-indirect-indirect-operand xmode) +; (define-derived-operand +; (name (.sym src32-An-indirect-indirect- xmode)) +; (comment (.str "m32c An indirect indirect destination " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args (Src32AnPrefixed)) +; (syntax (.str "[[$Src32AnPrefixed]]")) +; (base-ifield f-9-11) +; (encoding (+ (f-9-3 0) (f-18-1 0) Src32AnPrefixed)) +; (ifield-assertion (andif (eq f-9-3 0) (eq f-18-1 0))) +; (getter (mem32 xmode (indirect-addr Src32AnPrefixed))) +; (setter (set (mem32 xmode (indirect-addr Src32AnPrefixed)) newval)) +; ) +; ) + +; (src-An-indirect-indirect-operand QI) +; (src-An-indirect-indirect-operand HI) +; (src-An-indirect-indirect-operand SI) + +;------------------------------------------------------------- +; Relative indirect +;------------------------------------------------------------- + +(define-pmacro (src-relative-indirect-operand xmode) + (begin +; (define-derived-operand +; (name (.sym src32-24-8-SB-relative-indirect- xmode)) +; (comment (.str "m32c dsp:8[sb] relative source " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args (Dsp-24-u8)) +; (syntax "[${Dsp-24-u8}[sb]]") +; (base-ifield f-9-11) +; (encoding (+ (f-9-3 1) (f-18-2 2) Dsp-24-u8)) +; (ifield-assertion (andif (eq f-9-3 1) (eq f-18-2 2))) +; (getter (mem32 xmode (indirect-addr (add Dsp-24-u8 (reg h-sb))))) +; (setter (set (mem32 xmode (indirect-addr (add Dsp-24-u8 (reg h-sb)))) newval)) +; ) +; (define-derived-operand +; (name (.sym src32-24-16-SB-relative-indirect- xmode)) +; (comment (.str "m32c dsp:16[sb] relative source " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args (Dsp-24-u16)) +; (syntax "[${Dsp-24-u16}[sb]]") +; (base-ifield f-9-11) +; (encoding (+ (f-9-3 2) (f-18-2 2) Dsp-24-u16)) +; (ifield-assertion (andif (eq f-9-3 2) (eq f-18-2 2))) +; (getter (mem32 xmode (indirect-addr (add Dsp-24-u16 (reg h-sb))))) +; (setter (set (mem32 xmode (indirect-addr (add Dsp-24-u16 (reg h-sb)))) newval)) +; ) +; (define-derived-operand +; (name (.sym src32-24-8-FB-relative-indirect- xmode)) +; (comment (.str "m32c dsp:8[fb] relative source " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args (Dsp-24-s8)) +; (syntax "[${Dsp-24-s8}[fb]]") +; (base-ifield f-9-11) +; (encoding (+ (f-9-3 1) (f-18-2 3) Dsp-24-s8)) +; (ifield-assertion (andif (eq f-9-3 1) (eq f-18-2 3))) +; (getter (mem32 xmode (indirect-addr (add Dsp-24-s8 (reg h-fb))))) +; (setter (set (mem32 xmode (indirect-addr (add Dsp-24-s8 (reg h-fb)))) newval)) +; ) +; (define-derived-operand +; (name (.sym src32-24-16-FB-relative-indirect- xmode)) +; (comment (.str "m32c dsp:16[fb] relative source " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args (Dsp-24-s16)) +; (syntax "[${Dsp-24-s16}[fb]]") +; (base-ifield f-9-11) +; (encoding (+ (f-9-3 2) (f-18-2 3) Dsp-24-s16)) +; (ifield-assertion (andif (eq f-9-3 2) (eq f-18-2 3))) +; (getter (mem32 xmode (indirect-addr (add Dsp-24-s16 (reg h-fb))))) +; (setter (set (mem32 xmode (indirect-addr (add Dsp-24-s16 (reg h-fb)))) newval)) +; ) +; (define-derived-operand +; (name (.sym src32-24-8-An-relative-indirect- xmode)) +; (comment (.str "m32c dsp:8[An] relative indirect source " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args (Src32AnPrefixed Dsp-24-u8)) +; (syntax "[${Dsp-24-u8}[$Src32AnPrefixed]]") +; (base-ifield f-9-11) +; (encoding (+ (f-9-3 1) (f-18-1 0) Dsp-24-u8 Src32AnPrefixed)) +; (ifield-assertion (andif (eq f-9-3 1) (eq f-18-1 0))) +; (getter (mem32 xmode (indirect-addr (add Dsp-24-u8 Src32AnPrefixed)))) +; (setter (set (mem32 xmode (indirect-addr (add Dsp-24-u8 Src32AnPrefixed))) newval)) +; ) +; (define-derived-operand +; (name (.sym src32-24-16-An-relative-indirect- xmode)) +; (comment (.str "m32c dsp:16[An] relative source " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args (Src32AnPrefixed Dsp-24-u16)) +; (syntax "[${Dsp-24-u16}[$Src32AnPrefixed]]") +; (base-ifield f-9-11) +; (encoding (+ (f-9-3 2) (f-18-1 0) Dsp-24-u16 Src32AnPrefixed)) +; (ifield-assertion (andif (eq f-9-3 2) (eq f-18-1 0))) +; (getter (mem32 xmode (indirect-addr (add Dsp-24-u16 Src32AnPrefixed)))) +; (setter (set (mem32 xmode (indirect-addr (add Dsp-24-u16 Src32AnPrefixed))) newval)) +; ) +; (define-derived-operand +; (name (.sym src32-24-24-An-relative-indirect- xmode)) +; (comment (.str "m32c dsp:24[An] relative source " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args (Src32AnPrefixed Dsp-24-u24)) +; (syntax "[${Dsp-24-u24}[$Src32AnPrefixed]]") +; (base-ifield f-9-11) +; (encoding (+ (f-9-3 3) (f-18-1 0) Dsp-24-u24 Src32AnPrefixed)) +; (ifield-assertion (andif (eq f-9-3 3) (eq f-18-1 0))) +; (getter (mem32 xmode (indirect-addr (add Dsp-24-u24 Src32AnPrefixed)))) +; (setter (set (mem32 xmode (indirect-addr (add Dsp-24-u24 Src32AnPrefixed))) newval)) +; ) + ) +) + +; (src-relative-indirect-operand QI) +; (src-relative-indirect-operand HI) +; (src-relative-indirect-operand SI) + +;------------------------------------------------------------- +; Absolute Indirect address +;------------------------------------------------------------- + +(define-pmacro (src32-absolute-indirect offset base1 base2 xmode) + (begin +; (define-derived-operand +; (name (.sym src32- offset -16-absolute-indirect-derived- xmode)) +; (comment (.str "m32c absolute indirect address " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args ((.sym Dsp- offset -u16))) +; (syntax (.str "[${Dsp-" offset "-u16}]")) +; (base-ifield (.sym f- base1 -11)) +; (encoding (+ ((.sym f- base1 -3) 3) ((.sym f- base2 -2) 3) (.sym Dsp- offset -u16))) +; (ifield-assertion (andif (eq (.sym f- base1 -3) 3) (eq (.sym f- base2 -2) 3))) +; (getter (mem32 xmode (indirect-addr (.sym Dsp- offset -u16)))) +; (setter (set (mem32 xmode (indirect-addr (.sym Dsp- offset -u16))) newval)) +; ) +; (define-derived-operand +; (name (.sym src32- offset -24-absolute-indirect-derived- xmode)) +; (comment (.str "m32c absolute indirect address " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args ((.sym Dsp- offset -u24))) +; (syntax (.str "[${Dsp-" offset "-u24}]")) +; (base-ifield (.sym f- base1 -11)) +; (encoding (+ ((.sym f- base1 -3) 3) ((.sym f- base2 -2) 2) (.sym Dsp- offset -u24))) +; (ifield-assertion (andif (eq (.sym f- base1 -3) 3) (eq (.sym f- base2 -2) 2))) +; (getter (mem32 xmode (indirect-addr (.sym Dsp- offset -u24)))) +; (setter (set (mem32 xmode (indirect-addr (.sym Dsp- offset -u24))) newval)) +; ) + ) +) + +(src32-absolute-indirect 24 9 18 QI) +(src32-absolute-indirect 24 9 18 HI) +(src32-absolute-indirect 24 9 18 SI) + +;------------------------------------------------------------- +; Register relative source operands for short format insns +;------------------------------------------------------------- + +(define-pmacro (src-2-S-operands mach xmode base opc1 opc2 opc3) + (begin + (define-derived-operand + (name (.sym src mach -2-S-8-SB-relative- xmode)) + (comment (.str "m" mach "c SB relative address")) + (attrs (machine mach)) + (mode xmode) + (args (Dsp-8-u8)) + (syntax "${Dsp-8-u8}[sb]") + (base-ifield (.sym f- base -2)) + (encoding (+ ((.sym f- base -2) opc1) Dsp-8-u8)) + (ifield-assertion (eq (.sym f- base -2) opc1)) + (getter (c-call xmode (.str "operand_getter_" xmode) sb Dsp-8-u8)) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval sb Dsp-8-u8)) +; (getter (mem-mach mach xmode (indirect-addr (add (reg h-sb) Dsp-8-u8)))) +; (setter (set (mem-mach mach xmode (indirect-addr (add (reg h-sb) Dsp-8-u8))) newval)) + ) + (define-derived-operand + (name (.sym src mach -2-S-8-FB-relative- xmode)) + (comment (.str "m" mach "c FB relative address")) + (attrs (machine mach)) + (mode xmode) + (args (Dsp-8-s8)) + (syntax "${Dsp-8-s8}[fb]") + (base-ifield (.sym f- base -2)) + (encoding (+ ((.sym f- base -2) opc2) Dsp-8-s8)) + (ifield-assertion (eq (.sym f- base -2) opc2)) + (getter (c-call xmode (.str "operand_getter_" xmode) fb Dsp-8-s8)) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval fb Dsp-8-s8)) +; (getter (mem-mach mach xmode (indirect-addr (add (reg h-fb) Dsp-8-s8)))) +; (setter (set (mem-mach mach xmode (indirect-addr (add (reg h-fb) Dsp-8-s8))) newval)) + ) + (define-derived-operand + (name (.sym src mach -2-S-16-absolute- xmode)) + (comment (.str "m" mach "c absolute address")) + (attrs (machine mach)) + (mode xmode) + (args (Dsp-8-u16)) + (syntax "${Dsp-8-u16}") + (base-ifield (.sym f- base -2)) + (encoding (+ ((.sym f- base -2) opc3) Dsp-8-u16)) + (ifield-assertion (eq (.sym f- base -2) opc3)) + (getter (c-call xmode (.str "operand_getter_" xmode) (const 0) Dsp-8-u16)) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval (const 0) Dsp-8-u16)) +; (getter (mem-mach mach xmode Dsp-8-u16)) +; (setter (set (mem-mach mach xmode Dsp-8-u16) newval)) + ) + ) +) + +(src-2-S-operands 16 QI 6 1 2 3) +(src-2-S-operands 32 QI 2 2 3 1) +(src-2-S-operands 32 HI 2 2 3 1) + +;============================================================= +; Derived Operands +;------------------------------------------------------------- +; Destination +;------------------------------------------------------------- +; Rn direct +;------------------------------------------------------------- + +(define-pmacro (dst16-Rn-direct-operand xmode) + (begin + (define-derived-operand + (name (.sym dst16-Rn-direct- xmode)) + (comment (.str "m16c Rn direct destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args ((.sym Dst16Rn xmode))) + (syntax (.str "$Dst16Rn" xmode)) + (base-ifield f-12-4) + (encoding (+ (f-12-2 0) (.sym Dst16Rn xmode))) + (ifield-assertion (eq f-12-2 0)) + (getter (trunc xmode (.sym Dst16Rn xmode))) + (setter (set (.sym Dst16Rn xmode) newval)) + ) + ) +) + +(dst16-Rn-direct-operand QI) +(dst16-Rn-direct-operand HI) +(dst16-Rn-direct-operand SI) + +(define-derived-operand + (name dst16-Rn-direct-Ext-QI) + (comment "m16c Rn direct destination QI") + (attrs (machine 16)) + (mode HI) + (args (Dst16RnExtQI)) + (syntax "$Dst16RnExtQI") + (base-ifield f-12-4) + (encoding (+ (f-12-2 0) Dst16RnExtQI (f-15-1 0))) + (ifield-assertion (andif (eq f-12-2 0) (eq f-15-1 0))) + (getter (trunc QI (.sym Dst16RnExtQI))) + (setter (set Dst16RnExtQI newval)) +) + +(define-pmacro (dst32-Rn-direct-operand group base xmode) + (begin + (define-derived-operand + (name (.sym dst32-Rn-direct- group - xmode)) + (comment (.str "m32c Rn direct destination " xmode)) + (attrs (machine 32)) + (mode xmode) + (args ((.sym Dst32Rn group xmode))) + (syntax (.str "$Dst32Rn" group xmode)) + (base-ifield (.sym f- base -6)) + (encoding (+ ((.sym f- base -3) 4) (.sym Dst32Rn group xmode))) + (ifield-assertion (eq (.sym f- base -3) 4)) + (getter (trunc xmode (.sym Dst32Rn group xmode))) + (setter (set (.sym Dst32Rn group xmode) newval)) + ) + ) +) + +(dst32-Rn-direct-operand Unprefixed 4 QI) +(dst32-Rn-direct-operand Prefixed 12 QI) +(dst32-Rn-direct-operand Unprefixed 4 HI) +(dst32-Rn-direct-operand Prefixed 12 HI) +(dst32-Rn-direct-operand Unprefixed 4 SI) +(dst32-Rn-direct-operand Prefixed 12 SI) + +(define-pmacro (dst32-Rn-direct-Ext-operand group base1 base2 smode dmode) + (begin + (define-derived-operand + (name (.sym dst32-Rn-direct- group - smode)) + (comment (.str "m32c Rn direct destination " smode)) + (attrs (machine 32)) + (mode dmode) + (args ((.sym Dst32Rn group smode))) + (syntax (.str "$Dst32Rn" group smode)) + (base-ifield (.sym f- base1 -6)) + (encoding (+ ((.sym f- base1 -3) 4) ((.sym f- base2 -1) 1) (.sym Dst32Rn group smode))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 4) (eq (.sym f- base2 -1) 1))) + (getter (trunc smode (.sym Dst32Rn group smode))) + (setter (set (.sym Dst32Rn group smode) newval)) + ) + ) +) + +(dst32-Rn-direct-Ext-operand ExtUnprefixed 4 8 QI HI) +(dst32-Rn-direct-Ext-operand ExtUnprefixed 4 8 HI SI) + +(define-derived-operand + (name dst32-R3-direct-Unprefixed-HI) + (comment "m32c R3 direct HI") + (attrs (machine 32)) + (mode HI) + (args (R3)) + (syntax "$R3") + (base-ifield f-4-6) + (encoding (+ (f-4-3 4) (f-8-2 #x1))) + (ifield-assertion (andif (eq f-4-3 4) (eq f-8-2 #x1))) + (getter (trunc HI R3)) + (setter (set R3 newval)) +) +;------------------------------------------------------------- +; An direct +;------------------------------------------------------------- + +(define-pmacro (dst16-An-direct-operand xmode) + (begin + (define-derived-operand + (name (.sym dst16-An-direct- xmode)) + (comment (.str "m16c An direct destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args ((.sym Dst16An xmode))) + (syntax (.str "$Dst16An" xmode)) + (base-ifield f-12-4) + (encoding (+ (f-12-2 1) (f-14-1 0) (.sym Dst16An xmode))) + (ifield-assertion (andif (eq f-12-2 1) (eq f-14-1 0))) + (getter (trunc xmode (.sym Dst16An xmode))) + (setter (set (.sym Dst16An xmode) newval)) + ) + ) +) + +(dst16-An-direct-operand QI) +(dst16-An-direct-operand HI) +(dst16-An-direct-operand SI) + +(define-pmacro (dst32-An-direct-operand group base1 base2 xmode) + (begin + (define-derived-operand + (name (.sym dst32-An-direct- group - xmode)) + (comment (.str "m32c An direct destination " xmode)) + (attrs (machine 32)) + (mode xmode) + (args ((.sym Dst32An group xmode))) + (syntax (.str "$Dst32An" group xmode)) + (base-ifield (.sym f- base1 -6)) + (encoding (+ ((.sym f- base1 -3) 0) ((.sym f- base2 -1) 1) (.sym Dst32An group xmode))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 0) (eq (.sym f- base2 -1) 1))) + (getter (trunc xmode (.sym Dst32An group xmode))) + (setter (set (.sym Dst32An group xmode) newval)) + ) + ) +) + +(dst32-An-direct-operand Unprefixed 4 8 QI) +(dst32-An-direct-operand Prefixed 12 16 QI) +(dst32-An-direct-operand Unprefixed 4 8 HI) +(dst32-An-direct-operand Prefixed 12 16 HI) +(dst32-An-direct-operand Unprefixed 4 8 SI) +(dst32-An-direct-operand Prefixed 12 16 SI) + +;------------------------------------------------------------- +; An indirect +;------------------------------------------------------------- + +(define-pmacro (dst16-An-indirect-operand xmode) + (begin + (define-derived-operand + (name (.sym dst16-An-indirect- xmode)) + (comment (.str "m16c An indirect destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args (Dst16An)) + (syntax "[$Dst16An]") + (base-ifield f-12-4) + (encoding (+ (f-12-2 1) (f-14-1 1) Dst16An)) + (ifield-assertion (andif (eq f-12-2 1) (eq f-14-1 1))) + (getter (mem16 xmode Dst16An)) + (setter (set (mem16 xmode Dst16An) newval)) + ) + ) +) + +(dst16-An-indirect-operand QI) +(dst16-An-indirect-operand HI) +(dst16-An-indirect-operand SI) + +(define-derived-operand + (name dst16-An-indirect-Ext-QI) + (comment "m16c An indirect destination QI") + (attrs (machine 16)) + (mode HI) + (args (Dst16An)) + (syntax "[$Dst16An]") + (base-ifield f-12-4) + (encoding (+ (f-12-2 1) (f-14-1 1) Dst16An)) + (ifield-assertion (andif (eq f-12-2 1) (eq f-14-1 1))) + (getter (mem16 QI Dst16An)) + (setter (set (mem16 HI Dst16An) newval)) +) + +(define-pmacro (dst32-An-indirect-operand group base1 base2 smode dmode) + (begin + (define-derived-operand + (name (.sym dst32-An-indirect- group - smode)) + (comment (.str "m32c An indirect destination " smode)) + (attrs (machine 32)) + (mode dmode) + (args ((.sym Dst32An group))) + (syntax (.str "[$Dst32An" group "]")) + (base-ifield (.sym f- base1 -6)) + (encoding (+ ((.sym f- base1 -3) 0) ((.sym f- base2 -1) 0) (.sym Dst32An group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 0) (eq (.sym f- base2 -1) 0))) + (getter (c-call dmode (.str "operand_getter_" dmode) (.sym Dst32An group) + (const 0))) + (setter (c-call DFLT (.str "operand_setter_" dmode) newval + (.sym Dst32An group) (const 0))) +; (getter (mem32 smode (.sym Dst32An group))) +; (setter (set (mem32 dmode (.sym Dst32An group)) newval)) + ) + ) +) + +(dst32-An-indirect-operand Unprefixed 4 8 QI QI) +(dst32-An-indirect-operand Prefixed 12 16 QI QI) +(dst32-An-indirect-operand Unprefixed 4 8 HI HI) +(dst32-An-indirect-operand Prefixed 12 16 HI HI) +(dst32-An-indirect-operand Unprefixed 4 8 SI SI) +(dst32-An-indirect-operand Prefixed 12 16 SI SI) +(dst32-An-indirect-operand ExtUnprefixed 4 8 QI HI) +(dst32-An-indirect-operand ExtUnprefixed 4 8 HI SI) + +;------------------------------------------------------------- +; dsp:d[r] relative +;------------------------------------------------------------- + +(define-pmacro (dst16-relative-operand offset xmode) + (begin + (define-derived-operand + (name (.sym dst16- offset -8-SB-relative- xmode)) + (comment (.str "m16c dsp:8[sb] relative destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args ((.sym Dsp- offset -u8))) + (syntax (.str "${Dsp-" offset "-u8}[sb]")) + (base-ifield f-12-4) + (encoding (+ (f-12-4 #xA) (.sym Dsp- offset -u8))) + (ifield-assertion (eq f-12-4 #xA)) + (getter (mem16 xmode (add (.sym Dsp- offset -u8) (reg h-sb)))) + (setter (set (mem16 xmode (add (.sym Dsp- offset -u8) (reg h-sb))) newval)) + ) + (define-derived-operand + (name (.sym dst16- offset -16-SB-relative- xmode)) + (comment (.str "m16c dsp:16[sb] relative destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args ((.sym Dsp- offset -u16))) + (syntax (.str "${Dsp-" offset "-u16}[sb]")) + (base-ifield f-12-4) + (encoding (+ (f-12-4 #xE) (.sym Dsp- offset -u16))) + (ifield-assertion (eq f-12-4 #xE)) + (getter (mem16 xmode (add (.sym Dsp- offset -u16) (reg h-sb)))) + (setter (set (mem16 xmode (add (.sym Dsp- offset -u16) (reg h-sb))) newval)) + ) + (define-derived-operand + (name (.sym dst16- offset -8-FB-relative- xmode)) + (comment (.str "m16c dsp:8[fb] relative destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args ((.sym Dsp- offset -s8))) + (syntax (.str "${Dsp-" offset "-s8}[fb]")) + (base-ifield f-12-4) + (encoding (+ (f-12-4 #xB) (.sym Dsp- offset -s8))) + (ifield-assertion (eq f-12-4 #xB)) + (getter (mem16 xmode (add (.sym Dsp- offset -s8) (reg h-fb)))) + (setter (set (mem16 xmode (add (.sym Dsp- offset -s8) (reg h-fb))) newval)) + ) + (define-derived-operand + (name (.sym dst16- offset -8-An-relative- xmode)) + (comment (.str "m16c dsp:8[An] relative destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args (Dst16An (.sym Dsp- offset -u8))) + (syntax (.str "${Dsp-" offset "-u8}[$Dst16An]")) + (base-ifield f-12-4) + (encoding (+ (f-12-2 2) (f-14-1 0) (.sym Dsp- offset -u8) Dst16An)) + (ifield-assertion (andif (eq f-12-2 2) (eq f-14-1 0))) + (getter (mem16 xmode (add (.sym Dsp- offset -u8) Dst16An))) + (setter (set (mem16 xmode (add (.sym Dsp- offset -u8) Dst16An)) newval)) + ) + (define-derived-operand + (name (.sym dst16- offset -16-An-relative- xmode)) + (comment (.str "m16c dsp:16[An] relative destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args (Dst16An (.sym Dsp- offset -u16))) + (syntax (.str "${Dsp-" offset "-u16}[$Dst16An]")) + (base-ifield f-12-4) + (encoding (+ (f-12-2 3) (f-14-1 0) (.sym Dsp- offset -u16) Dst16An)) + (ifield-assertion (andif (eq f-12-2 3) (eq f-14-1 0))) + (getter (mem16 xmode (add (.sym Dsp- offset -u16) Dst16An))) + (setter (set (mem16 xmode (add (.sym Dsp- offset -u16) Dst16An)) newval)) + ) + (define-derived-operand + (name (.sym dst16- offset -20-An-relative- xmode)) + (comment (.str "m16c dsp:20[An] relative destination " xmode)) + (attrs (machine 16)) + (mode xmode) + (args (Dst16An (.sym Dsp- offset -u20))) + (syntax (.str "${Dsp-" offset "-u20}[$Dst16An]")) + (base-ifield f-12-4) + (encoding (+ (f-12-2 3) (f-14-1 0) (.sym Dsp- offset -u20) Dst16An)) + (ifield-assertion (andif (eq f-12-2 3) (eq f-14-1 0))) + (getter (mem16 xmode (add (.sym Dsp- offset -u20) Dst16An))) + (setter (set (mem16 xmode (add (.sym Dsp- offset -u20) Dst16An)) newval)) + ) + ) +) + +(dst16-relative-operand 16 QI) +(dst16-relative-operand 24 QI) +(dst16-relative-operand 32 QI) +(dst16-relative-operand 40 QI) +(dst16-relative-operand 48 QI) +(dst16-relative-operand 16 HI) +(dst16-relative-operand 24 HI) +(dst16-relative-operand 32 HI) +(dst16-relative-operand 40 HI) +(dst16-relative-operand 48 HI) +(dst16-relative-operand 16 SI) +(dst16-relative-operand 24 SI) +(dst16-relative-operand 32 SI) +(dst16-relative-operand 40 SI) +(dst16-relative-operand 48 SI) + +(define-pmacro (dst16-relative-Ext-operand offset smode dmode) + (begin + (define-derived-operand + (name (.sym dst16- offset -8-SB-relative-Ext- smode)) + (comment (.str "m16c dsp:8[sb] relative destination " smode)) + (attrs (machine 16)) + (mode dmode) + (args ((.sym Dsp- offset -u8))) + (syntax (.str "${Dsp-" offset "-u8}[sb]")) + (base-ifield f-12-4) + (encoding (+ (f-12-4 #xA) (.sym Dsp- offset -u8))) + (ifield-assertion (eq f-12-4 #xA)) + (getter (mem16 smode (add (.sym Dsp- offset -u8) (reg h-sb)))) + (setter (set (mem16 dmode (add (.sym Dsp- offset -u8) (reg h-sb))) newval)) + ) + (define-derived-operand + (name (.sym dst16- offset -16-SB-relative-Ext- smode)) + (comment (.str "m16c dsp:16[sb] relative destination " smode)) + (attrs (machine 16)) + (mode dmode) + (args ((.sym Dsp- offset -u16))) + (syntax (.str "${Dsp-" offset "-u16}[sb]")) + (base-ifield f-12-4) + (encoding (+ (f-12-4 #xE) (.sym Dsp- offset -u16))) + (ifield-assertion (eq f-12-4 #xE)) + (getter (mem16 smode (add (.sym Dsp- offset -u16) (reg h-sb)))) + (setter (set (mem16 dmode (add (.sym Dsp- offset -u16) (reg h-sb))) newval)) + ) + (define-derived-operand + (name (.sym dst16- offset -8-FB-relative-Ext- smode)) + (comment (.str "m16c dsp:8[fb] relative destination " smode)) + (attrs (machine 16)) + (mode dmode) + (args ((.sym Dsp- offset -s8))) + (syntax (.str "${Dsp-" offset "-s8}[fb]")) + (base-ifield f-12-4) + (encoding (+ (f-12-4 #xB) (.sym Dsp- offset -s8))) + (ifield-assertion (eq f-12-4 #xB)) + (getter (mem16 smode (add (.sym Dsp- offset -s8) (reg h-fb)))) + (setter (set (mem16 dmode (add (.sym Dsp- offset -s8) (reg h-fb))) newval)) + ) + (define-derived-operand + (name (.sym dst16- offset -8-An-relative-Ext- smode)) + (comment (.str "m16c dsp:8[An] relative destination " smode)) + (attrs (machine 16)) + (mode dmode) + (args (Dst16An (.sym Dsp- offset -u8))) + (syntax (.str "${Dsp-" offset "-u8}[$Dst16An]")) + (base-ifield f-12-4) + (encoding (+ (f-12-2 2) (f-14-1 0) (.sym Dsp- offset -u8) Dst16An)) + (ifield-assertion (andif (eq f-12-2 2) (eq f-14-1 0))) + (getter (mem16 smode (add (.sym Dsp- offset -u8) Dst16An))) + (setter (set (mem16 dmode (add (.sym Dsp- offset -u8) Dst16An)) newval)) + ) + (define-derived-operand + (name (.sym dst16- offset -16-An-relative-Ext- smode)) + (comment (.str "m16c dsp:16[An] relative destination " smode)) + (attrs (machine 16)) + (mode dmode) + (args (Dst16An (.sym Dsp- offset -u16))) + (syntax (.str "${Dsp-" offset "-u16}[$Dst16An]")) + (base-ifield f-12-4) + (encoding (+ (f-12-2 3) (f-14-1 0) (.sym Dsp- offset -u16) Dst16An)) + (ifield-assertion (andif (eq f-12-2 3) (eq f-14-1 0))) + (getter (mem16 smode (add (.sym Dsp- offset -u16) Dst16An))) + (setter (set (mem16 dmode (add (.sym Dsp- offset -u16) Dst16An)) newval)) + ) + ) +) + +(dst16-relative-Ext-operand 16 QI HI) + +(define-pmacro (dst32-relative-operand offset group base1 base2 smode dmode) + (begin + (define-derived-operand + (name (.sym dst32- offset -8-SB-relative- group - smode)) + (comment (.str "m32c dsp:8[sb] relative destination " smode)) + (attrs (machine 32)) + (mode dmode) + (args ((.sym Dsp- offset -u8))) + (syntax (.str "${Dsp-" offset "-u8}[sb]")) + (base-ifield (.sym f- base1 -6)) + (encoding (+ ((.sym f- base1 -3) 1) ((.sym f- base2 -2) 2) (.sym Dsp- offset -u8))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 1) (eq (.sym f- base2 -2) 2))) + (getter (c-call dmode (.str "operand_getter_" dmode) sb (.sym Dsp- offset -u8))) + (setter (c-call DFLT (.str "operand_setter_" dmode) newval sb (.sym Dsp- offset -u8))) +; (getter (mem32 smode (add (.sym Dsp- offset -u8) (reg h-sb)))) +; (setter (set (mem32 dmode (add (.sym Dsp- offset -u8) (reg h-sb))) newval)) + ) + (define-derived-operand + (name (.sym dst32- offset -16-SB-relative- group - smode)) + (comment (.str "m32c dsp:16[sb] relative destination " smode)) + (attrs (machine 32)) + (mode dmode) + (args ((.sym Dsp- offset -u16))) + (syntax (.str "${Dsp-" offset "-u16}[sb]")) + (base-ifield (.sym f- base1 -6)) + (encoding (+ ((.sym f- base1 -3) 2) ((.sym f- base2 -2) 2) (.sym Dsp- offset -u16))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 2) (eq (.sym f- base2 -2) 2))) + (getter (c-call dmode (.str "operand_getter_" dmode) sb (.sym Dsp- offset -u16))) + (setter (c-call DFLT (.str "operand_setter_" dmode) newval sb (.sym Dsp- offset -u16))) +; (getter (mem32 smode (add (.sym Dsp- offset -u16) (reg h-sb)))) +; (setter (set (mem32 dmode (add (.sym Dsp- offset -u16) (reg h-sb))) newval)) + ) + (define-derived-operand + (name (.sym dst32- offset -8-FB-relative- group - smode)) + (comment (.str "m32c dsp:8[fb] relative destination " smode)) + (attrs (machine 32)) + (mode dmode) + (args ((.sym Dsp- offset -s8))) + (syntax (.str "${Dsp-" offset "-s8}[fb]")) + (base-ifield (.sym f- base1 -6)) + (encoding (+ ((.sym f- base1 -3) 1) ((.sym f- base2 -2) 3) (.sym Dsp- offset -s8))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 1) (eq (.sym f- base2 -2) 3))) + (getter (c-call dmode (.str "operand_getter_" dmode) fb (.sym Dsp- offset -s8))) + (setter (c-call DFLT (.str "operand_setter_" dmode) newval fb (.sym Dsp- offset -s8))) +; (getter (mem32 smode (add (.sym Dsp- offset -s8) (reg h-fb)))) +; (setter (set (mem32 dmode (add (.sym Dsp- offset -s8) (reg h-fb))) newval)) + ) + (define-derived-operand + (name (.sym dst32- offset -16-FB-relative- group - smode)) + (comment (.str "m32c dsp:16[fb] relative destination " smode)) + (attrs (machine 32)) + (mode dmode) + (args ((.sym Dsp- offset -s16))) + (syntax (.str "${Dsp-" offset "-s16}[fb]")) + (base-ifield (.sym f- base1 -6)) + (encoding (+ ((.sym f- base1 -3) 2) ((.sym f- base2 -2) 3) (.sym Dsp- offset -s16))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 2) (eq (.sym f- base2 -2) 3))) + (getter (c-call dmode (.str "operand_getter_" dmode) fb (.sym Dsp- offset -s16))) + (setter (c-call DFLT (.str "operand_setter_" dmode) newval fb (.sym Dsp- offset -s16))) +; (getter (mem32 smode (add (.sym Dsp- offset -s16) (reg h-fb)))) +; (setter (set (mem32 dmode (add (.sym Dsp- offset -s16) (reg h-fb))) newval)) + ) + (define-derived-operand + (name (.sym dst32- offset -8-An-relative- group - smode)) + (comment (.str "m32c dsp:8[An] relative destination " smode)) + (attrs (machine 32)) + (mode dmode) + (args ((.sym Dst32An group) (.sym Dsp- offset -u8))) + (syntax (.str "${Dsp-" offset "-u8}[$Dst32An" group "]")) + (base-ifield (.sym f- base1 -6)) + (encoding (+ ((.sym f- base1 -3) 1) ((.sym f- base2 -1) 0) (.sym Dsp- offset -u8) (.sym Dst32An group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 1) (eq (.sym f- base2 -1) 0))) + (getter (c-call dmode (.str "operand_getter_" dmode) (.sym Dst32An group) (.sym Dsp- offset -u8))) + (setter (c-call DFLT (.str "operand_setter_" dmode) newval (.sym Dst32An group) (.sym Dsp- offset -u8))) +; (getter (mem32 smode (add (.sym Dsp- offset -u8) (.sym Dst32An group)))) +; (setter (set (mem32 dmode (add (.sym Dsp- offset -u8) (.sym Dst32An group))) newval)) + ) + (define-derived-operand + (name (.sym dst32- offset -16-An-relative- group - smode)) + (comment (.str "m32c dsp:16[An] relative destination " smode)) + (attrs (machine 32)) + (mode dmode) + (args ((.sym Dst32An group) (.sym Dsp- offset -u16))) + (syntax (.str "${Dsp-" offset "-u16}[$Dst32An" group "]")) + (base-ifield (.sym f- base1 -6)) + (encoding (+ ((.sym f- base1 -3) 2) ((.sym f- base2 -1) 0) (.sym Dsp- offset -u16) (.sym Dst32An group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 2) (eq (.sym f- base2 -1) 0))) + (getter (c-call dmode (.str "operand_getter_" dmode) (.sym Dst32An group) (.sym Dsp- offset -u16))) + (setter (c-call DFLT (.str "operand_setter_" dmode) newval (.sym Dst32An group) (.sym Dsp- offset -u16))) +; (getter (mem32 smode (add (.sym Dsp- offset -u16) (.sym Dst32An group)))) +; (setter (set (mem32 dmode (add (.sym Dsp- offset -u16) (.sym Dst32An group))) newval)) + ) + (define-derived-operand + (name (.sym dst32- offset -24-An-relative- group - smode)) + (comment (.str "m32c dsp:16[An] relative destination " smode)) + (attrs (machine 32)) + (mode dmode) + (args ((.sym Dst32An group) (.sym Dsp- offset -u24))) + (syntax (.str "${Dsp-" offset "-u24}[$Dst32An" group "]")) + (base-ifield (.sym f- base1 -6)) + (encoding (+ ((.sym f- base1 -3) 3) ((.sym f- base2 -1) 0) (.sym Dsp- offset -u24) (.sym Dst32An group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 3) (eq (.sym f- base2 -1) 0))) + (getter (c-call dmode (.str "operand_getter_" dmode) (.sym Dst32An group) (.sym Dsp- offset -u24))) + (setter (c-call DFLT (.str "operand_setter_" dmode) newval (.sym Dst32An group) (.sym Dsp- offset -u24))) +; (getter (mem32 smode (add (.sym Dsp- offset -u24) (.sym Dst32An group)))) +; (setter (set (mem32 dmode (add (.sym Dsp- offset -u24) (.sym Dst32An group))) newval)) + ) + ) +) + +(dst32-relative-operand 16 Unprefixed 4 8 QI QI) +(dst32-relative-operand 24 Unprefixed 4 8 QI QI) +(dst32-relative-operand 32 Unprefixed 4 8 QI QI) +(dst32-relative-operand 40 Unprefixed 4 8 QI QI) +(dst32-relative-operand 16 Unprefixed 4 8 HI HI) +(dst32-relative-operand 24 Unprefixed 4 8 HI HI) +(dst32-relative-operand 32 Unprefixed 4 8 HI HI) +(dst32-relative-operand 40 Unprefixed 4 8 HI HI) +(dst32-relative-operand 16 Unprefixed 4 8 SI SI) +(dst32-relative-operand 24 Unprefixed 4 8 SI SI) +(dst32-relative-operand 32 Unprefixed 4 8 SI SI) +(dst32-relative-operand 40 Unprefixed 4 8 SI SI) + +(dst32-relative-operand 24 Prefixed 12 16 QI QI) +(dst32-relative-operand 32 Prefixed 12 16 QI QI) +(dst32-relative-operand 40 Prefixed 12 16 QI QI) +(dst32-relative-operand 48 Prefixed 12 16 QI QI) +(dst32-relative-operand 24 Prefixed 12 16 HI HI) +(dst32-relative-operand 32 Prefixed 12 16 HI HI) +(dst32-relative-operand 40 Prefixed 12 16 HI HI) +(dst32-relative-operand 48 Prefixed 12 16 HI HI) +(dst32-relative-operand 24 Prefixed 12 16 SI SI) +(dst32-relative-operand 32 Prefixed 12 16 SI SI) +(dst32-relative-operand 40 Prefixed 12 16 SI SI) +(dst32-relative-operand 48 Prefixed 12 16 SI SI) + +(dst32-relative-operand 16 ExtUnprefixed 4 8 QI HI) +(dst32-relative-operand 16 ExtUnprefixed 4 8 HI SI) + +;------------------------------------------------------------- +; Absolute address +;------------------------------------------------------------- + +(define-pmacro (dst16-absolute offset xmode) + (begin + (define-derived-operand + (name (.sym dst16- offset -16-absolute- xmode)) + (comment (.str "m16c absolute address " xmode)) + (attrs (machine 16)) + (mode xmode) + (args ((.sym Dsp- offset -u16))) + (syntax (.str "${Dsp-" offset "-u16}")) + (base-ifield f-12-4) + (encoding (+ (f-12-4 #xF) (.sym Dsp- offset -u16))) + (ifield-assertion (eq f-12-4 #xF)) + (getter (mem16 xmode (.sym Dsp- offset -u16))) + (setter (set (mem16 xmode (.sym Dsp- offset -u16)) newval)) + ) + ) +) + +(dst16-absolute 16 QI) +(dst16-absolute 24 QI) +(dst16-absolute 32 QI) +(dst16-absolute 40 QI) +(dst16-absolute 48 QI) +(dst16-absolute 16 HI) +(dst16-absolute 24 HI) +(dst16-absolute 32 HI) +(dst16-absolute 40 HI) +(dst16-absolute 48 HI) +(dst16-absolute 16 SI) +(dst16-absolute 24 SI) +(dst16-absolute 32 SI) +(dst16-absolute 40 SI) +(dst16-absolute 48 SI) + +(define-derived-operand + (name dst16-16-16-absolute-Ext-QI) + (comment "m16c absolute address QI") + (attrs (machine 16)) + (mode HI) + (args (Dsp-16-u16)) + (syntax "${Dsp-16-u16}") + (base-ifield f-12-4) + (encoding (+ (f-12-4 #xF) Dsp-16-u16)) + (ifield-assertion (eq f-12-4 #xF)) + (getter (mem16 QI Dsp-16-u16)) + (setter (set (mem16 HI Dsp-16-u16) newval)) +) + +(define-pmacro (dst32-absolute offset group base1 base2 smode dmode) + (begin + (define-derived-operand + (name (.sym dst32- offset -16-absolute- group - smode)) + (comment (.str "m32c absolute address " smode)) + (attrs (machine 32)) + (mode dmode) + (args ((.sym Dsp- offset -u16))) + (syntax (.str "${Dsp-" offset "-u16}")) + (base-ifield (.sym f- base1 -6)) + (encoding (+ ((.sym f- base1 -3) 3) ((.sym f- base2 -2) 3) (.sym Dsp- offset -u16))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 3) (eq (.sym f- base2 -2) 3))) + (getter (c-call smode (.str "operand_getter_" smode) (const 0) (.sym Dsp- offset -u16))) + (setter (c-call DFLT (.str "operand_setter_" dmode) newval (const 0) (.sym Dsp- offset -u16))) +; (getter (mem32 smode (.sym Dsp- offset -u16))) +; (setter (set (mem32 dmode (.sym Dsp- offset -u16)) newval)) + ) + (define-derived-operand + (name (.sym dst32- offset -24-absolute- group - smode)) + (comment (.str "m32c absolute address " smode)) + (attrs (machine 32)) + (mode dmode) + (args ((.sym Dsp- offset -u24))) + (syntax (.str "${Dsp-" offset "-u24}")) + (base-ifield (.sym f- base1 -6)) + (encoding (+ ((.sym f- base1 -3) 3) ((.sym f- base2 -2) 2) (.sym Dsp- offset -u24))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 3) (eq (.sym f- base2 -2) 2))) + (getter (c-call smode (.str "operand_getter_" smode) (const 0) (.sym Dsp- offset -u24))) + (setter (c-call DFLT (.str "operand_setter_" dmode) newval (const 0) (.sym Dsp- offset -u24))) +; (getter (mem32 smode (.sym Dsp- offset -u24))) +; (setter (set (mem32 dmode (.sym Dsp- offset -u24)) newval)) + ) + ) +) + +(dst32-absolute 16 Unprefixed 4 8 QI QI) +(dst32-absolute 24 Unprefixed 4 8 QI QI) +(dst32-absolute 32 Unprefixed 4 8 QI QI) +(dst32-absolute 40 Unprefixed 4 8 QI QI) +(dst32-absolute 16 Unprefixed 4 8 HI HI) +(dst32-absolute 24 Unprefixed 4 8 HI HI) +(dst32-absolute 32 Unprefixed 4 8 HI HI) +(dst32-absolute 40 Unprefixed 4 8 HI HI) +(dst32-absolute 16 Unprefixed 4 8 SI SI) +(dst32-absolute 24 Unprefixed 4 8 SI SI) +(dst32-absolute 32 Unprefixed 4 8 SI SI) +(dst32-absolute 40 Unprefixed 4 8 SI SI) + +(dst32-absolute 24 Prefixed 12 16 QI QI) +(dst32-absolute 32 Prefixed 12 16 QI QI) +(dst32-absolute 40 Prefixed 12 16 QI QI) +(dst32-absolute 48 Prefixed 12 16 QI QI) +(dst32-absolute 24 Prefixed 12 16 HI HI) +(dst32-absolute 32 Prefixed 12 16 HI HI) +(dst32-absolute 40 Prefixed 12 16 HI HI) +(dst32-absolute 48 Prefixed 12 16 HI HI) +(dst32-absolute 24 Prefixed 12 16 SI SI) +(dst32-absolute 32 Prefixed 12 16 SI SI) +(dst32-absolute 40 Prefixed 12 16 SI SI) +(dst32-absolute 48 Prefixed 12 16 SI SI) + +(dst32-absolute 16 ExtUnprefixed 4 8 QI HI) +(dst32-absolute 16 ExtUnprefixed 4 8 HI SI) + +;------------------------------------------------------------- +; An indirect indirect +;------------------------------------------------------------- + +;(define-pmacro (dst-An-indirect-indirect-operand xmode) +; (define-derived-operand +; (name (.sym dst32-An-indirect-indirect- xmode)) +; (comment (.str "m32c An indirect indirect destination " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args (Dst32AnPrefixed)) +; (syntax (.str "[[$Dst32AnPrefixed]]")) +; (base-ifield f-12-6) +; (encoding (+ (f-12-3 0) (f-16-1 0) Dst32AnPrefixed)) +; (ifield-assertion (andif (eq f-12-3 0) (eq f-16-1 0))) +; (getter (mem32 xmode (indirect-addr Dst32AnPrefixed))) +; (setter (set (mem32 xmode (indirect-addr Dst32AnPrefixed)) newval)) +; ) +;) + +; (dst-An-indirect-indirect-operand QI) +; (dst-An-indirect-indirect-operand HI) +; (dst-An-indirect-indirect-operand SI) + +;------------------------------------------------------------- +; Relative indirect +;------------------------------------------------------------- + +(define-pmacro (dst-relative-indirect-operand offset xmode) + (begin +; (define-derived-operand +; (name (.sym dst32- offset -8-SB-relative-indirect- xmode)) +; (comment (.str "m32c dsp:8[sb] relative destination " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args ((.sym Dsp- offset -u8))) +; (syntax (.str "[${Dsp-" offset "-u8}[sb]]")) +; (base-ifield f-12-6) +; (encoding (+ (f-12-3 1) (f-16-2 2) (.sym Dsp- offset -u8))) +; (ifield-assertion (andif (eq f-12-3 1) (eq f-16-2 2))) +; (getter (mem32 xmode (indirect-addr (add (.sym Dsp- offset -u8) (reg h-sb))))) +; (setter (set (mem32 xmode (indirect-addr (add (.sym Dsp- offset -u8) (reg h-sb)))) newval)) +; ) +; (define-derived-operand +; (name (.sym dst32- offset -16-SB-relative-indirect- xmode)) +; (comment (.str "m32c dsp:16[sb] relative destination " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args ((.sym Dsp- offset -u16))) +; (syntax (.str "[${Dsp-" offset "-u16}[sb]]")) +; (base-ifield f-12-6) +; (encoding (+ (f-12-3 2) (f-16-2 2) (.sym Dsp- offset -u16))) +; (ifield-assertion (andif (eq f-12-3 2) (eq f-16-2 2))) +; (getter (mem32 xmode (indirect-addr (add (.sym Dsp- offset -u16) (reg h-sb))))) +; (setter (set (mem32 xmode (indirect-addr (add (.sym Dsp- offset -u16) (reg h-sb)))) newval)) +; ) +; (define-derived-operand +; (name (.sym dst32- offset -8-FB-relative-indirect- xmode)) +; (comment (.str "m32c dsp:8[fb] relative destination " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args ((.sym Dsp- offset -s8))) +; (syntax (.str "[${Dsp-" offset "-s8}[fb]]")) +; (base-ifield f-12-6) +; (encoding (+ (f-12-3 1) (f-16-2 3) (.sym Dsp- offset -s8))) +; (ifield-assertion (andif (eq f-12-3 1) (eq f-16-2 3))) +; (getter (mem32 xmode (indirect-addr (add (.sym Dsp- offset -s8) (reg h-fb))))) +; (setter (set (mem32 xmode (indirect-addr (add (.sym Dsp- offset -s8) (reg h-fb)))) newval)) +; ) +; (define-derived-operand +; (name (.sym dst32- offset -16-FB-relative-indirect- xmode)) +; (comment (.str "m32c dsp:16[fb] relative destination " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args ((.sym Dsp- offset -s16))) +; (syntax (.str "[${Dsp-" offset "-s16}[fb]]")) +; (base-ifield f-12-6) +; (encoding (+ (f-12-3 2) (f-16-2 3) (.sym Dsp- offset -s16))) +; (ifield-assertion (andif (eq f-12-3 2) (eq f-16-2 3))) +; (getter (mem32 xmode (indirect-addr (add (.sym Dsp- offset -s16) (reg h-fb))))) +; (setter (set (mem32 xmode (indirect-addr (add (.sym Dsp- offset -s16) (reg h-fb)))) newval)) +; ) +; (define-derived-operand +; (name (.sym dst32- offset -8-An-relative-indirect- xmode)) +; (comment (.str "m32c dsp:8[An] relative indirect destination " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args (Dst32AnPrefixed (.sym Dsp- offset -u8))) +; (syntax (.str "[${Dsp-" offset "-u8}[$Dst32AnPrefixed]]")) +; (base-ifield f-12-6) +; (encoding (+ (f-12-3 1) (f-16-1 0) (.sym Dsp- offset -u8) Dst32AnPrefixed)) +; (ifield-assertion (andif (eq f-12-3 1) (eq f-16-1 0))) +; (getter (mem32 xmode (indirect-addr (add (.sym Dsp- offset -u8) Dst32AnPrefixed)))) +; (setter (set (mem32 xmode (indirect-addr (add (.sym Dsp- offset -u8) Dst32AnPrefixed))) newval)) +; ) +; (define-derived-operand +; (name (.sym dst32- offset -16-An-relative-indirect- xmode)) +; (comment (.str "m32c dsp:16[An] relative destination " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args (Dst32AnPrefixed (.sym Dsp- offset -u16))) +; (syntax (.str "[${Dsp-" offset "-u16}[$Dst32AnPrefixed]]")) +; (base-ifield f-12-6) +; (encoding (+ (f-12-3 2) (f-16-1 0) (.sym Dsp- offset -u16) Dst32AnPrefixed)) +; (ifield-assertion (andif (eq f-12-3 2) (eq f-16-1 0))) +; (getter (mem32 xmode (indirect-addr (add (.sym Dsp- offset -u16) Dst32AnPrefixed)))) +; (setter (set (mem32 xmode (indirect-addr (add (.sym Dsp- offset -u16) Dst32AnPrefixed))) newval)) +; ) +; (define-derived-operand +; (name (.sym dst32- offset -24-An-relative-indirect- xmode)) +; (comment (.str "m32c dsp:24[An] relative destination " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args (Dst32AnPrefixed (.sym Dsp- offset -u24))) +; (syntax (.str "[${Dsp-" offset "-u24}[$Dst32AnPrefixed]]")) +; (base-ifield f-12-6) +; (encoding (+ (f-12-3 3) (f-16-1 0) (.sym Dsp- offset -u24) Dst32AnPrefixed)) +; (ifield-assertion (andif (eq f-12-3 3) (eq f-16-1 0))) +; (getter (mem32 xmode (indirect-addr (add (.sym Dsp- offset -u24) Dst32AnPrefixed)))) +; (setter (set (mem32 xmode (indirect-addr (add (.sym Dsp- offset -u24) Dst32AnPrefixed))) newval)) +; ) + ) +) + +; (dst-relative-indirect-operand 24 QI) +; (dst-relative-indirect-operand 32 QI) +; (dst-relative-indirect-operand 40 QI) +; (dst-relative-indirect-operand 48 QI) +; (dst-relative-indirect-operand 24 HI) +; (dst-relative-indirect-operand 32 HI) +; (dst-relative-indirect-operand 40 HI) +; (dst-relative-indirect-operand 48 HI) +; (dst-relative-indirect-operand 24 SI) +; (dst-relative-indirect-operand 32 SI) +; (dst-relative-indirect-operand 40 SI) +; (dst-relative-indirect-operand 48 SI) + +;------------------------------------------------------------- +; Absolute indirect +;------------------------------------------------------------- + +(define-pmacro (dst-absolute-indirect offset xmode) + (begin +; (define-derived-operand +; (name (.sym dst32- offset -16-absolute-indirect-derived- xmode)) +; (comment (.str "m32c absolute indirect address " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args ((.sym Dsp- offset -u16))) +; (syntax (.str "[${Dsp-" offset "-u16}]")) +; (base-ifield f-12-6) +; (encoding (+ (f-12-3 3) (f-16-2 3) (.sym Dsp- offset -u16))) +; (ifield-assertion (andif (eq f-12-3 3) (eq f-16-2 3))) +; (getter (mem32 xmode (indirect-addr (.sym Dsp- offset -u16)))) +; (setter (set (mem32 xmode (indirect-addr (.sym Dsp- offset -u16))) newval)) +; ) +; (define-derived-operand +; (name (.sym dst32- offset -24-absolute-indirect-derived- xmode)) +; (comment (.str "m32c absolute indirect address " xmode)) +; (attrs (machine 32)) +; (mode xmode) +; (args ((.sym Dsp- offset -u24))) +; (syntax (.str "[${Dsp-" offset "-u24}]")) +; (base-ifield f-12-6) +; (encoding (+ (f-12-3 3) (f-16-2 2) (.sym Dsp- offset -u24))) +; (ifield-assertion (andif (eq f-12-3 3) (eq f-16-2 2))) +; (getter (mem32 xmode (indirect-addr (.sym Dsp- offset -u24)))) +; (setter (set (mem32 xmode (indirect-addr (.sym Dsp- offset -u24))) newval)) +; ) + ) +) + +(dst-absolute-indirect 24 QI) +(dst-absolute-indirect 32 QI) +(dst-absolute-indirect 40 QI) +(dst-absolute-indirect 48 QI) +(dst-absolute-indirect 24 HI) +(dst-absolute-indirect 32 HI) +(dst-absolute-indirect 40 HI) +(dst-absolute-indirect 48 HI) +(dst-absolute-indirect 24 SI) +(dst-absolute-indirect 32 SI) +(dst-absolute-indirect 40 SI) +(dst-absolute-indirect 48 SI) + +;------------------------------------------------------------- +; Bit operands +;------------------------------------------------------------- +(define-pmacro (get-register-bit reg bitno) + (and (srl reg bitno) 1) +) + +(define-pmacro (set-register-bit reg bitno value) + (set reg (or (and reg (inv (sll 1 bitno))) + (sll (and QI value 1) bitno))) +) + +(define-pmacro (get-memory-bit mach base bitno) + (and (srl (mem-mach mach QI (add base (div bitno 8))) + (mod bitno 8)) + 1) +) + +(define-pmacro (set-memory-bit mach base bitno value) + (sequence ((USI addr)) + (set addr (add base (div bitno 8))) + (set (mem-mach mach QI addr) + (or (and (mem-mach mach QI addr) + (inv (sll 1 (mod bitno 8)))) + (sll (and QI value 1) (mod bitno 8))))) +) + +;------------------------------------------------------------- +; Rn direct +;------------------------------------------------------------- + +(define-derived-operand + (name bit16-Rn-direct) + (comment "m16c Rn direct bit") + (attrs (machine 16)) + (mode BI) + (args (Bitno16R Bit16Rn)) + (syntax "$Bitno16R,$Bit16Rn") + (base-ifield f-12-4) + (encoding (+ (f-12-2 0) Bit16Rn Bitno16R)) + (ifield-assertion (eq f-12-2 0)) + (getter (get-register-bit Bit16Rn Bitno16R)) + (setter (set-register-bit Bit16Rn Bitno16R newval)) +) + +(define-pmacro (bit32-Rn-direct-operand group base) + (begin + (define-derived-operand + (name (.sym bit32-Rn-direct- group)) + (comment "m32c Rn direct bit") + (attrs (machine 32)) + (mode BI) + (args ((.sym Bitno32 group) (.sym Bit32Rn group))) + (syntax (.str "$Bitno32" group ",$Bit32Rn" group)) + (base-ifield (.sym f- base -6)) + (encoding (+ ((.sym f- base -3) 4) (.sym Bit32Rn group) (.sym Bitno32 group))) + (ifield-assertion (eq (.sym f- base -3) 4)) + (getter (get-register-bit (.sym Bit32Rn group) (.sym Bitno32 group))) + (setter (set-register-bit (.sym Bit32Rn group) (.sym Bitno32 group) newval)) + ) + ) +) + +(bit32-Rn-direct-operand Unprefixed 4) +(bit32-Rn-direct-operand Prefixed 12) + +;------------------------------------------------------------- +; An direct +;------------------------------------------------------------- + +(define-derived-operand + (name bit16-An-direct) + (comment "m16c An direct bit") + (attrs (machine 16)) + (mode BI) + (args (Bitno16R Bit16An)) + (syntax "$Bitno16R,$Bit16An") + (base-ifield f-12-4) + (encoding (+ (f-12-2 1) (f-14-1 0) Bit16An Bitno16R)) + (ifield-assertion (andif (eq f-12-2 1) (eq f-14-1 0))) + (getter (get-register-bit Bit16An Bitno16R)) + (setter (set-register-bit Bit16An Bitno16R newval)) +) + +(define-pmacro (bit32-An-direct-operand group base1 base2) + (begin + (define-derived-operand + (name (.sym bit32-An-direct- group)) + (comment "m32c An direct bit") + (attrs (machine 32)) + (mode BI) + (args ((.sym Bitno32 group) (.sym Bit32An group))) + (syntax (.str "$Bitno32" group ",$Bit32An" group)) + (base-ifield (.sym f- base1 -6)) + (encoding (+ ((.sym f- base1 -3) 0) ((.sym f- base2 -1) 1) (.sym Bit32An group) (.sym Bitno32 group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 0) (eq (.sym f- base2 -1) 1))) + (getter (get-register-bit (.sym Bit32An group) (.sym Bitno32 group))) + (setter (set-register-bit (.sym Bit32An group) (.sym Bitno32 group) newval)) + ) + ) +) + +(bit32-An-direct-operand Unprefixed 4 8) +(bit32-An-direct-operand Prefixed 12 16) + +;------------------------------------------------------------- +; An indirect +;------------------------------------------------------------- + +(define-derived-operand + (name bit16-An-indirect) + (comment "m16c An indirect bit") + (attrs (machine 16)) + (mode BI) + (args (Bit16An)) + (syntax "[$Bit16An]") + (base-ifield f-12-4) + (encoding (+ (f-12-2 1) (f-14-1 1) Bit16An)) + (ifield-assertion (andif (eq f-12-2 1) (eq f-14-1 1))) + (getter (get-memory-bit 16 0 Bit16An)) + (setter (set-memory-bit 16 0 Bit16An newval)) +) + +(define-pmacro (bit32-An-indirect-operand group base1 base2) + (begin + (define-derived-operand + (name (.sym bit32-An-indirect- group)) + (comment "m32c An indirect destination ") + (attrs (machine 32)) + (mode BI) + (args ((.sym Bitno32 group) (.sym Bit32An group))) + (syntax (.str "$Bitno32" group ",[$Bit32An" group "]")) + (base-ifield (.sym f- base1 -6)) + (encoding (+ ((.sym f- base1 -3) 0) ((.sym f- base2 -1) 0) (.sym Bit32An group) (.sym Bitno32 group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 0) (eq (.sym f- base2 -1) 0))) + (getter (get-memory-bit 32 (.sym Bit32An group) (.sym Bitno32 group))) + (setter (set-memory-bit 32 (.sym Bit32An group) (.sym Bitno32 group) newval)) + ) + ) +) + +(bit32-An-indirect-operand Unprefixed 4 8) +(bit32-An-indirect-operand Prefixed 12 16) + +;------------------------------------------------------------- +; dsp:d[r] relative +;------------------------------------------------------------- + +(define-pmacro (bit16-relative-operand offset) + (begin + (define-derived-operand + (name (.sym bit16- offset -8-SB-relative)) + (comment (.str "m16c dsp:8[sb] relative bit " xmode)) + (attrs (machine 16)) + (mode BI) + (args ((.sym BitBase16- offset -u8))) + (syntax (.str "${BitBase16-" offset "-u8}[sb]")) + (base-ifield f-12-4) + (encoding (+ (f-12-4 #xA) (.sym BitBase16- offset -u8))) + (ifield-assertion (eq f-12-4 #xA)) + (getter (get-memory-bit 16 (reg h-sb) (.sym BitBase16- offset -u8))) + (setter (set-memory-bit 16 (reg h-sb) (.sym BitBase16- offset -u8) newval)) + ) + (define-derived-operand + (name (.sym bit16- offset -16-SB-relative)) + (comment (.str "m16c dsp:16[sb] relative bit " xmode)) + (attrs (machine 16)) + (mode BI) + (args ((.sym BitBase16- offset -u16))) + (syntax (.str "${BitBase16-" offset "-u16}[sb]")) + (base-ifield f-12-4) + (encoding (+ (f-12-4 #xE) (.sym BitBase16- offset -u16))) + (ifield-assertion (eq f-12-4 #xE)) + (getter (get-memory-bit 16 (reg h-sb) (.sym BitBase16- offset -u16))) + (setter (set-memory-bit 16 (reg h-sb) (.sym BitBase16- offset -u16) newval)) + ) + (define-derived-operand + (name (.sym bit16- offset -8-FB-relative)) + (comment (.str "m16c dsp:8[fb] relative bit " xmode)) + (attrs (machine 16)) + (mode BI) + (args ((.sym BitBase16- offset -s8))) + (syntax (.str "${BitBase16-" offset "-s8}[fb]")) + (base-ifield f-12-4) + (encoding (+ (f-12-4 #xB) (.sym BitBase16- offset -s8))) + (ifield-assertion (eq f-12-4 #xB)) + (getter (get-memory-bit 16 (reg h-fb) (.sym BitBase16- offset -s8))) + (setter (set-memory-bit 16 (reg h-fb) (.sym BitBase16- offset -s8) newval)) + ) + (define-derived-operand + (name (.sym bit16- offset -8-An-relative)) + (comment (.str "m16c dsp:8[An] relative bit " xmode)) + (attrs (machine 16)) + (mode BI) + (args (Bit16An (.sym Dsp- offset -u8))) + (syntax (.str "${Dsp-" offset "-u8}[$Bit16An]")) + (base-ifield f-12-4) + (encoding (+ (f-12-2 2) (f-14-1 0) (.sym Dsp- offset -u8) Bit16An)) + (ifield-assertion (andif (eq f-12-2 2) (eq f-14-1 0))) + (getter (get-memory-bit 16 (.sym Dsp- offset -u8) Bit16An)) + (setter (set-memory-bit 16 (.sym Dsp- offset -u8) Bit16An newval)) + ) + (define-derived-operand + (name (.sym bit16- offset -16-An-relative)) + (comment (.str "m16c dsp:16[An] relative bit " xmode)) + (attrs (machine 16)) + (mode BI) + (args (Bit16An (.sym Dsp- offset -u16))) + (syntax (.str "${Dsp-" offset "-u16}[$Bit16An]")) + (base-ifield f-12-4) + (encoding (+ (f-12-2 3) (f-14-1 0) (.sym Dsp- offset -u16) Bit16An)) + (ifield-assertion (andif (eq f-12-2 3) (eq f-14-1 0))) + (getter (get-memory-bit 16 (.sym Dsp- offset -u16) Bit16An)) + (setter (set-memory-bit 16 (.sym Dsp- offset -u16) Bit16An newval)) + ) + ) +) + +(bit16-relative-operand 16) + +(define-pmacro (bit32-relative-operand offset group base1 base2) + (begin + (define-derived-operand + (name (.sym bit32- offset -11-SB-relative- group)) + (comment "m32c bit,base:11[sb] relative bit") + (attrs (machine 32)) + (mode BI) + (args ((.sym BitBase32- offset -u11- group))) + (syntax (.str "${BitBase32-" offset "-u11-" group "}[sb]")) + (base-ifield (.sym f- base1 -12)) + (encoding (+ ((.sym f- base1 -3) 1) ((.sym f- base2 -2) 2) (.sym BitBase32- offset -u11- group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 1) (eq (.sym f- base2 -2) 2))) + (getter (get-memory-bit 32 (reg h-sb) (.sym BitBase32- offset -u11- group))) + (setter (set-memory-bit 32 (reg h-sb) (.sym BitBase32- offset -u11- group) newval)) + ) + (define-derived-operand + (name (.sym bit32- offset -19-SB-relative- group)) + (comment "m32c bit,base:19[sb] relative bit") + (attrs (machine 32)) + (mode BI) + (args ((.sym BitBase32- offset -u19- group))) + (syntax (.str "${BitBase32-" offset "-u19-" group "}[sb]")) + (base-ifield (.sym f- base1 -12)) + (encoding (+ ((.sym f- base1 -3) 2) ((.sym f- base2 -2) 2) (.sym BitBase32- offset -u19- group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 2) (eq (.sym f- base2 -2) 2))) + (getter (get-memory-bit 32 (reg h-sb) (.sym BitBase32- offset -u19- group))) + (setter (set-memory-bit 32 (reg h-sb) (.sym BitBase32- offset -u19- group) newval)) + ) + (define-derived-operand + (name (.sym bit32- offset -11-FB-relative- group)) + (comment "m32c bit,base:11[fb] relative bit") + (attrs (machine 32)) + (mode BI) + (args ((.sym BitBase32- offset -s11- group))) + (syntax (.str "${BitBase32-" offset "-s11-" group "}[fb]")) + (base-ifield (.sym f- base1 -12)) + (encoding (+ ((.sym f- base1 -3) 1) ((.sym f- base2 -2) 3) (.sym BitBase32- offset -s11- group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 1) (eq (.sym f- base2 -2) 3))) + (getter (get-memory-bit 32 (reg h-fb) (.sym BitBase32- offset -s11- group))) + (setter (set-memory-bit 32 (reg h-fb) (.sym BitBase32- offset -s11- group) newval)) + ) + (define-derived-operand + (name (.sym bit32- offset -19-FB-relative- group)) + (comment "m32c bit,base:19[fb] relative bit") + (attrs (machine 32)) + (mode BI) + (args ((.sym BitBase32- offset -s19- group))) + (syntax (.str "${BitBase32-" offset "-s19-" group "}[fb]")) + (base-ifield (.sym f- base1 -12)) + (encoding (+ ((.sym f- base1 -3) 2) ((.sym f- base2 -2) 3) (.sym BitBase32- offset -s19- group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 2) (eq (.sym f- base2 -2) 3))) + (getter (get-memory-bit 32 (reg h-fb) (.sym BitBase32- offset -s19- group))) + (setter (set-memory-bit 32 (reg h-fb) (.sym BitBase32- offset -s19- group) newval)) + ) + (define-derived-operand + (name (.sym bit32- offset -11-An-relative- group)) + (comment "m32c bit,base:11[An] relative bit") + (attrs (machine 32)) + (mode BI) + (args ((.sym BitBase32- offset -u11- group) (.sym Bit32An group))) + (syntax (.str "${BitBase32-" offset "-u11-" group "}[$Bit32An" group "]")) + (base-ifield (.sym f- base1 -12)) + (encoding (+ ((.sym f- base1 -3) 1) ((.sym f- base2 -1) 0) (.sym BitBase32- offset -u11- group) (.sym Bit32An group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 1) (eq (.sym f- base2 -1) 0))) + (getter (get-memory-bit 32 (.sym Bit32An group) (.sym BitBase32- offset -u11- group))) + (setter (set-memory-bit 32 (.sym Bit32An group) (.sym BitBase32- offset -u11- group) newval)) + ) + (define-derived-operand + (name (.sym bit32- offset -19-An-relative- group)) + (comment "m32c bit,base:19[An] relative bit") + (attrs (machine 32)) + (mode BI) + (args ((.sym BitBase32- offset -u19- group) (.sym Bit32An group))) + (syntax (.str "${BitBase32-" offset "-u19-" group "}[$Bit32An" group "]")) + (base-ifield (.sym f- base1 -12)) + (encoding (+ ((.sym f- base1 -3) 2) ((.sym f- base2 -1) 0) (.sym BitBase32- offset -u19- group) (.sym Bit32An group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 2) (eq (.sym f- base2 -1) 0))) + (getter (get-memory-bit 32 (.sym Bit32An group) (.sym BitBase32- offset -u19- group))) + (setter (set-memory-bit 32 (.sym Bit32An group) (.sym BitBase32- offset -u19- group) newval)) + ) + (define-derived-operand + (name (.sym bit32- offset -27-An-relative- group)) + (comment "m32c bit,base:27[An] relative bit") + (attrs (machine 32)) + (mode BI) + (args ((.sym BitBase32- offset -u27- group) (.sym Bit32An group))) + (syntax (.str "${BitBase32-" offset "-u27-" group "}[$Bit32An" group "]")) + (base-ifield (.sym f- base1 -12)) + (encoding (+ ((.sym f- base1 -3) 3) ((.sym f- base2 -1) 0) (.sym BitBase32- offset -u27- group) (.sym Bit32An group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 3) (eq (.sym f- base2 -1) 0))) + (getter (get-memory-bit 32 (.sym Bit32An group) (.sym BitBase32- offset -u27- group))) + (setter (set-memory-bit 32 (.sym Bit32An group) (.sym BitBase32- offset -u27- group) newval)) + ) + ) +) + +(bit32-relative-operand 16 Unprefixed 4 8) +(bit32-relative-operand 24 Prefixed 12 16) + +(define-derived-operand + (name bit16-11-SB-relative-S) + (comment "m16c bit,base:11[sb] relative bit") + (attrs (machine 16)) + (mode BI) + (args (BitBase16-8-u11-S)) + (syntax "${BitBase16-8-u11-S}[sb]") + (base-ifield (.sym f-5-3)) + (encoding (+ BitBase16-8-u11-S)) +; (ifield-assertion (#t)) + (getter (get-memory-bit 16 (reg h-sb) BitBase16-8-u11-S)) + (setter (set-memory-bit 16 (reg h-sb) BitBase16-8-u11-S newval)) +) + +(define-derived-operand + (name Rn16-push-S-derived) + (comment "m16c r0[lh] for push,pop short version") + (attrs (machine 16)) + (mode QI) + (args (Rn16-push-S)) + (syntax "${Rn16-push-S}") + (base-ifield (.sym f-4-1)) + (encoding (+ Rn16-push-S)) +; (ifield-assertion (#t)) + (getter (trunc QI Rn16-push-S)) + (setter (set Rn16-push-S newval)) +) + +(define-derived-operand + (name An16-push-S-derived) + (comment "m16c r0[lh] for push,pop short version") + (attrs (machine 16)) + (mode HI) + (args (An16-push-S)) + (syntax "${An16-push-S}") + (base-ifield (.sym f-4-1)) + (encoding (+ An16-push-S)) +; (ifield-assertion (#t)) + (getter (trunc QI An16-push-S)) + (setter (set An16-push-S newval)) +) + +;------------------------------------------------------------- +; Absolute address +;------------------------------------------------------------- + +(define-pmacro (bit16-absolute offset) + (begin + (define-derived-operand + (name (.sym bit16- offset -16-absolute)) + (comment "m16c absolute address") + (attrs (machine 16)) + (mode BI) + (args ((.sym BitBase16- offset -u16))) + (syntax (.str "${BitBase16-" offset "-u16}")) + (base-ifield f-12-4) + (encoding (+ (f-12-4 #xF) (.sym BitBase16- offset -u16))) + (ifield-assertion (eq f-12-4 #xF)) + (getter (get-memory-bit 16 0 (.sym BitBase16- offset -u16))) + (setter (set-memory-bit 16 0 (.sym BitBase16- offset -u16) newval)) + ) + ) +) + +(bit16-absolute 16) + +(define-pmacro (bit32-absolute offset group base1 base2) + (begin + (define-derived-operand + (name (.sym bit32- offset -19-absolute- group)) + (comment "m32c absolute address bit") + (attrs (machine 32)) + (mode BI) + (args ((.sym BitBase32- offset -u19- group))) + (syntax (.str "${BitBase32-" offset "-u19-" group "}")) + (base-ifield (.sym f- base1 -12)) + (encoding (+ ((.sym f- base1 -3) 3) ((.sym f- base2 -2) 3) (.sym BitBase32- offset -u19- group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 3) (eq (.sym f- base2 -2) 3))) + (getter (get-memory-bit 32 0 (.sym BitBase32- offset -u19- group))) + (setter (set-memory-bit 32 0 (.sym BitBase32- offset -u19- group) newval)) + ) + (define-derived-operand + (name (.sym bit32- offset -27-absolute- group)) + (comment "m32c absolute address bit") + (attrs (machine 32)) + (mode BI) + (args ((.sym BitBase32- offset -u27- group))) + (syntax (.str "${BitBase32-" offset "-u27-" group "}")) + (base-ifield (.sym f- base1 -12)) + (encoding (+ ((.sym f- base1 -3) 3) ((.sym f- base2 -2) 2) (.sym BitBase32- offset -u27- group))) + (ifield-assertion (andif (eq (.sym f- base1 -3) 3) (eq (.sym f- base2 -2) 2))) + (getter (get-memory-bit 32 0 (.sym BitBase32- offset -u27- group))) + (setter (set-memory-bit 32 0 (.sym BitBase32- offset -u27- group) newval)) + ) + ) +) + +(bit32-absolute 16 Unprefixed 4 8) +(bit32-absolute 24 Prefixed 12 16) + +;------------------------------------------------------------- +; Destination operands for short fomat insns +;------------------------------------------------------------- + +(define-derived-operand + (name dst16-3-S-R0l-direct-QI) + (comment "m16c R0l direct QI") + (attrs (machine 16)) + (mode QI) + (args (R0l)) + (syntax "r0l") + (base-ifield f-5-3) + (encoding (+ (f-5-3 4))) + (ifield-assertion (eq f-5-3 4)) + (getter (trunc QI R0l)) + (setter (set R0l newval)) +) +(define-derived-operand + (name dst16-3-S-R0h-direct-QI) + (comment "m16c R0h direct QI") + (attrs (machine 16)) + (mode QI) + (args (R0h)) + (syntax "r0h") + (base-ifield f-5-3) + (encoding (+ (f-5-3 3))) + (ifield-assertion (eq f-5-3 3)) + (getter (trunc QI R0h)) + (setter (set R0h newval)) +) +(define-derived-operand + (name dst16-3-S-8-8-SB-relative-QI) + (comment "m16c SB relative QI") + (attrs (machine 16)) + (mode QI) + (args (Dsp-8-u8)) + (syntax "${Dsp-8-u8}[sb]") + (base-ifield f-5-3) + (encoding (+ (f-5-3 5) Dsp-8-u8)) + (ifield-assertion (eq f-5-3 5)) + (getter (mem16 QI (add Dsp-8-u8 (reg h-sb)))) + (setter (set (mem16 QI (add Dsp-8-u8 (reg h-sb))) newval)) +) +(define-derived-operand + (name dst16-3-S-8-8-FB-relative-QI) + (comment "m16c FB relative QI") + (attrs (machine 16)) + (mode QI) + (args (Dsp-8-s8)) + (syntax "${Dsp-8-s8}[fb]") + (base-ifield f-5-3) + (encoding (+ (f-5-3 6) Dsp-8-s8)) + (ifield-assertion (eq f-5-3 6)) + (getter (mem16 QI (add Dsp-8-s8 (reg h-fb)))) + (setter (set (mem16 QI (add Dsp-8-s8 (reg h-fb))) newval)) +) +(define-derived-operand + (name dst16-3-S-8-16-absolute-QI) + (comment "m16c absolute address QI") + (attrs (machine 16)) + (mode QI) + (args (Dsp-8-u16)) + (syntax "${Dsp-8-u16}") + (base-ifield f-5-3) + (encoding (+ (f-5-3 7) Dsp-8-u16)) + (ifield-assertion (eq f-5-3 7)) + (getter (mem16 QI Dsp-8-u16)) + (setter (set (mem16 QI Dsp-8-u16) newval)) +) +(define-derived-operand + (name dst16-3-S-16-8-SB-relative-QI) + (comment "m16c SB relative QI") + (attrs (machine 16)) + (mode QI) + (args (Dsp-16-u8)) + (syntax "${Dsp-16-u8}[sb]") + (base-ifield f-5-3) + (encoding (+ (f-5-3 5) Dsp-16-u8)) + (ifield-assertion (eq f-5-3 5)) + (getter (mem16 QI (add Dsp-16-u8 (reg h-sb)))) + (setter (set (mem16 QI (add Dsp-16-u8 (reg h-sb))) newval)) +) +(define-derived-operand + (name dst16-3-S-16-8-FB-relative-QI) + (comment "m16c FB relative QI") + (attrs (machine 16)) + (mode QI) + (args (Dsp-16-s8)) + (syntax "${Dsp-16-s8}[fb]") + (base-ifield f-5-3) + (encoding (+ (f-5-3 6) Dsp-16-s8)) + (ifield-assertion (eq f-5-3 6)) + (getter (mem16 QI (add Dsp-16-s8 (reg h-fb)))) + (setter (set (mem16 QI (add Dsp-16-s8 (reg h-fb))) newval)) +) +(define-derived-operand + (name dst16-3-S-16-16-absolute-QI) + (comment "m16c absolute address QI") + (attrs (machine 16)) + (mode QI) + (args (Dsp-16-u16)) + (syntax "${Dsp-16-u16}") + (base-ifield f-5-3) + (encoding (+ (f-5-3 7) Dsp-16-u16)) + (ifield-assertion (eq f-5-3 7)) + (getter (mem16 QI Dsp-16-u16)) + (setter (set (mem16 QI Dsp-16-u16) newval)) +) +(define-derived-operand + (name srcdst16-r0l-r0h-S-derived) + (comment "m16c r0l/r0h operand for short format insns") + (attrs (machine 16)) + (mode SI) + (args (SrcDst16-r0l-r0h-S-normal)) + (syntax "${SrcDst16-r0l-r0h-S-normal}") + (base-ifield f-6-3) + (encoding (+ (f-6-2 0) SrcDst16-r0l-r0h-S-normal)) + (ifield-assertion (eq f-6-2 0)) + (getter (trunc SI SrcDst16-r0l-r0h-S-normal)) + (setter ()) ; no setter +) +(define-derived-operand + (name dst32-2-S-R0l-direct-QI) + (comment "m32c R0l direct QI") + (attrs (machine 32)) + (mode QI) + (args (R0l)) + (syntax "r0l") + (base-ifield f-2-2) + (encoding (+ (f-2-2 0))) + (ifield-assertion (eq f-2-2 0)) + (getter (trunc QI R0l)) + (setter (set R0l newval)) +) +(define-derived-operand + (name dst32-2-S-R0-direct-HI) + (comment "m32c R0 direct HI") + (attrs (machine 32)) + (mode HI) + (args (R0)) + (syntax "r0") + (base-ifield f-2-2) + (encoding (+ (f-2-2 0))) + (ifield-assertion (eq f-2-2 0)) + (getter (trunc HI R0)) + (setter (set R0 newval)) +) +(define-derived-operand + (name dst32-1-S-A0-direct-HI) + (comment "m32c A0 direct HI") + (attrs (machine 32)) + (mode HI) + (args (A0)) + (syntax "a0") + (base-ifield f-7-1) + (encoding (+ (f-7-1 0))) + (ifield-assertion (eq f-7-1 0)) + (getter (trunc HI A0)) + (setter (set A0 newval)) +) +(define-derived-operand + (name dst32-1-S-A1-direct-HI) + (comment "m32c A1 direct HI") + (attrs (machine 32)) + (mode HI) + (args (A1)) + (syntax "a1") + (base-ifield f-7-1) + (encoding (+ (f-7-1 1))) + (ifield-assertion (eq f-7-1 1)) + (getter (trunc HI A1)) + (setter (set A1 newval)) +) +(define-pmacro (dst32-2-S-operands xmode) + (begin + (define-derived-operand + (name (.sym dst32-2-S-8-SB-relative- xmode)) + (comment "m32c SB relative for short binary insns") + (attrs (machine 32)) + (mode xmode) + (args (Dsp-8-u8)) + (syntax "${Dsp-8-u8}[sb]") + (base-ifield f-2-2) + (encoding (+ (f-2-2 2) Dsp-8-u8)) + (ifield-assertion (eq f-2-2 2)) + (getter (c-call xmode (.str "operand_getter_" xmode) sb Dsp-8-u8)) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval sb Dsp-8-u8)) +; (getter (mem32 xmode (add Dsp-8-u8 (reg h-sb)))) +; (setter (set (mem32 xmode (add Dsp-8-u8 (reg h-sb))) newval)) + ) + (define-derived-operand + (name (.sym dst32-2-S-8-FB-relative- xmode)) + (comment "m32c FB relative for short binary insns") + (attrs (machine 32)) + (mode xmode) + (args (Dsp-8-s8)) + (syntax "${Dsp-8-s8}[fb]") + (base-ifield f-2-2) + (encoding (+ (f-2-2 3) Dsp-8-s8)) + (ifield-assertion (eq f-2-2 3)) + (getter (c-call xmode (.str "operand_getter_" xmode) fb Dsp-8-s8)) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval fb Dsp-8-s8)) +; (getter (mem32 xmode (add Dsp-8-s8 (reg h-fb)))) +; (setter (set (mem32 xmode (add Dsp-8-s8 (reg h-fb))) newval)) + ) + (define-derived-operand + (name (.sym dst32-2-S-16-absolute- xmode)) + (comment "m32c absolute address for short binary insns") + (attrs (machine 32)) + (mode xmode) + (args (Dsp-8-u16)) + (syntax "${Dsp-8-u16}") + (base-ifield f-2-2) + (encoding (+ (f-2-2 1) Dsp-8-u16)) + (ifield-assertion (eq f-2-2 1)) + (getter (c-call xmode (.str "operand_getter_" xmode) (const 0) Dsp-8-u16)) + (setter (c-call DFLT (.str "operand_setter_" xmode) newval (const 0) Dsp-8-u16)) +; (getter (mem32 xmode Dsp-8-u16)) +; (setter (set (mem32 xmode Dsp-8-u16) newval)) + ) +; (define-derived-operand +; (name (.sym dst32-2-S-8-SB-relative-indirect- xmode)) +; (comment "m32c SB relative for short binary insns") +; (attrs (machine 32)) +; (mode xmode) +; (args (Dsp-16-u8)) +; (syntax "[${Dsp-16-u8}[sb]]") +; (base-ifield f-10-2) +; (encoding (+ (f-10-2 2) Dsp-16-u8)) +; (ifield-assertion (eq f-10-2 2)) +; (getter (mem32 xmode (indirect-addr (add Dsp-16-u8 (reg h-sb))))) +; (setter (set (mem32 xmode (indirect-addr (add Dsp-16-u8 (reg h-sb)))) newval)) +; ) +; (define-derived-operand +; (name (.sym dst32-2-S-8-FB-relative-indirect- xmode)) +; (comment "m32c FB relative for short binary insns") +; (attrs (machine 32)) +; (mode xmode) +; (args (Dsp-16-s8)) +; (syntax "[${Dsp-16-s8}[fb]]") +; (base-ifield f-10-2) +; (encoding (+ (f-10-2 3) Dsp-16-s8)) +; (ifield-assertion (eq f-10-2 3)) +; (getter (mem32 xmode (indirect-addr (add Dsp-16-s8 (reg h-fb))))) +; (setter (set (mem32 xmode (indirect-addr (add Dsp-16-s8 (reg h-fb)))) newval)) +; ) +; (define-derived-operand +; (name (.sym dst32-2-S-16-absolute-indirect- xmode)) +; (comment "m32c absolute address for short binary insns") +; (attrs (machine 32)) +; (mode xmode) +; (args (Dsp-16-u16)) +; (syntax "[${Dsp-16-u16}]") +; (base-ifield f-10-2) +; (encoding (+ (f-10-2 1) Dsp-16-u16)) +; (ifield-assertion (eq f-10-2 1)) +; (getter (mem32 xmode (indirect-addr Dsp-16-u16))) +; (setter (set (mem32 xmode (indirect-addr Dsp-16-u16)) newval)) +; ) + ) +) + +(dst32-2-S-operands QI) +(dst32-2-S-operands HI) +(dst32-2-S-operands SI) + +;============================================================= +; Anyof operands +;------------------------------------------------------------- +; Source operands with no additional fields +;------------------------------------------------------------- + +(define-pmacro (src16-basic-operand xmode) + (begin + (define-anyof-operand + (name (.sym src16-basic- xmode)) + (comment (.str "m16c source operand of size " xmode " with no additional fields")) + (attrs (machine 16)) + (mode xmode) + (choices + (.sym src16-Rn-direct- xmode) + (.sym src16-An-direct- xmode) + (.sym src16-An-indirect- xmode) + ) + ) + ) +) +(src16-basic-operand QI) +(src16-basic-operand HI) + +(define-pmacro (src32-basic-operand xmode) + (begin + (define-anyof-operand + (name (.sym src32-basic-Unprefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with no additional fields")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym src32-Rn-direct-Unprefixed- xmode) + (.sym src32-An-direct-Unprefixed- xmode) + (.sym src32-An-indirect-Unprefixed- xmode) + ) + ) + (define-anyof-operand + (name (.sym src32-basic-Prefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with no additional fields")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym src32-Rn-direct-Prefixed- xmode) + (.sym src32-An-direct-Prefixed- xmode) + (.sym src32-An-indirect-Prefixed- xmode) + ) + ) +; (define-anyof-operand +; (name (.sym src32-basic-indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " indirect with no additional fields")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym src32-An-indirect-indirect- xmode) +; ) +; ) + ) +) + +(src32-basic-operand QI) +(src32-basic-operand HI) +(src32-basic-operand SI) + +(define-anyof-operand + (name src32-basic-ExtPrefixed-QI) + (comment "m32c source operand of size QI with no additional fields") + (attrs (machine 32)) + (mode QI) + (choices + src32-Rn-direct-Prefixed-QI + src32-An-indirect-Prefixed-QI + ) +) + +;------------------------------------------------------------- +; Source operands with additional fields at offset 16 bits +;------------------------------------------------------------- + +(define-pmacro (src16-16-operand xmode) + (begin + (define-anyof-operand + (name (.sym src16-16-8- xmode)) + (comment (.str "m16c source operand of size " xmode " with additional 8 bit fields at offset 16")) + (attrs (machine 16)) + (mode xmode) + (choices + (.sym src16-16-8-An-relative- xmode) + (.sym src16-16-8-SB-relative- xmode) + (.sym src16-16-8-FB-relative- xmode) + ) + ) + (define-anyof-operand + (name (.sym src16-16-16- xmode)) + (comment (.str "m16c source operand of size " xmode " with additional 16 bit fields at offset 16")) + (attrs (machine 16)) + (mode xmode) + (choices + (.sym src16-16-16-An-relative- xmode) + (.sym src16-16-16-SB-relative- xmode) + (.sym src16-16-16-absolute- xmode) + ) + ) + ) +) +(src16-16-operand QI) +(src16-16-operand HI) + +(define-pmacro (src32-16-operand xmode) + (begin + (define-anyof-operand + (name (.sym src32-16-8-Unprefixed- xmode)) + (comment (.str "m32c source operand of size " xmode " with additional 8 bit fields at offset 16")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym src32-16-8-An-relative-Unprefixed- xmode) + (.sym src32-16-8-SB-relative-Unprefixed- xmode) + (.sym src32-16-8-FB-relative-Unprefixed- xmode) + ) + ) + (define-anyof-operand + (name (.sym src32-16-16-Unprefixed- xmode)) + (comment (.str "m32c source operand of size " xmode " with additional 16 bit fields at offset 16")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym src32-16-16-An-relative-Unprefixed- xmode) + (.sym src32-16-16-SB-relative-Unprefixed- xmode) + (.sym src32-16-16-FB-relative-Unprefixed- xmode) + (.sym src32-16-16-absolute-Unprefixed- xmode) + ) + ) + (define-anyof-operand + (name (.sym src32-16-24-Unprefixed- xmode)) + (comment (.str "m32c source operand of size " xmode " with additional 24 bit fields at offset 16")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym src32-16-24-An-relative-Unprefixed- xmode) + (.sym src32-16-24-absolute-Unprefixed- xmode) + ) + ) + ) +) + +(src32-16-operand QI) +(src32-16-operand HI) +(src32-16-operand SI) + +;------------------------------------------------------------- +; Source operands with additional fields at offset 24 bits +;------------------------------------------------------------- + +(define-pmacro (src-24-operand group xmode) + (begin + (define-anyof-operand + (name (.sym src32-24-8- group - xmode)) + (comment (.str "m32c source operand of size " xmode " with additional 8 bit fields at offset 24")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym src32-24-8-An-relative- group - xmode) + (.sym src32-24-8-SB-relative- group - xmode) + (.sym src32-24-8-FB-relative- group - xmode) + ) + ) + (define-anyof-operand + (name (.sym src32-24-16- group - xmode)) + (comment (.str "m32c source operand of size " xmode " with additional 16 bit fields at offset 16")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym src32-24-16-An-relative- group - xmode) + (.sym src32-24-16-SB-relative- group - xmode) + (.sym src32-24-16-FB-relative- group - xmode) + (.sym src32-24-16-absolute- group - xmode) + ) + ) + (define-anyof-operand + (name (.sym src32-24-24- group - xmode)) + (comment (.str "m32c source operand of size " xmode " with additional 24 bit fields at offset 16")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym src32-24-24-An-relative- group - xmode) + (.sym src32-24-24-absolute- group - xmode) + ) + ) + ) +) + +(src-24-operand Prefixed QI) +(src-24-operand Prefixed HI) +(src-24-operand Prefixed SI) + +(define-pmacro (src-24-indirect-operand xmode) + (begin +; (define-anyof-operand +; (name (.sym src32-24-8-indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 24")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym src32-24-8-An-relative-indirect- xmode) +; (.sym src32-24-8-SB-relative-indirect- xmode) +; (.sym src32-24-8-FB-relative-indirect- xmode) +; ) +; ) +; (define-anyof-operand +; (name (.sym src32-24-16-indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 24")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym src32-24-16-An-relative-indirect- xmode) +; (.sym src32-24-16-SB-relative-indirect- xmode) +; (.sym src32-24-16-FB-relative-indirect- xmode) +; ) +; ) +; (define-anyof-operand +; (name (.sym src32-24-24-indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 24")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym src32-24-24-An-relative-indirect- xmode) +; ) +; ) +; (define-anyof-operand +; (name (.sym src32-24-16-absolute-indirect- xmode)) +; (comment (.str "m32c source operand of size " xmode " 16 bit absolute indirect")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym src32-24-16-absolute-indirect-derived- xmode) +; ) +; ) +; (define-anyof-operand +; (name (.sym src32-24-24-absolute-indirect- xmode)) +; (comment (.str "m32c source operand of size " xmode " 24 bit absolute indirect")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym src32-24-24-absolute-indirect-derived- xmode) +; ) +; ) + ) +) + +; (src-24-indirect-operand QI) +; (src-24-indirect-operand HI) +; (src-24-indirect-operand SI) + +;------------------------------------------------------------- +; Destination operands with no additional fields +;------------------------------------------------------------- + +(define-pmacro (dst16-basic-operand xmode) + (begin + (define-anyof-operand + (name (.sym dst16-basic- xmode)) + (comment (.str "m16c destination operand of size " xmode " with no additional fields")) + (attrs (machine 16)) + (mode xmode) + (choices + (.sym dst16-Rn-direct- xmode) + (.sym dst16-An-direct- xmode) + (.sym dst16-An-indirect- xmode) + ) + ) + ) +) + +(dst16-basic-operand QI) +(dst16-basic-operand HI) +(dst16-basic-operand SI) + +(define-pmacro (dst32-basic-operand xmode) + (begin + (define-anyof-operand + (name (.sym dst32-basic-Unprefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with no additional fields")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-Rn-direct-Unprefixed- xmode) + (.sym dst32-An-direct-Unprefixed- xmode) + (.sym dst32-An-indirect-Unprefixed- xmode) + ) + ) + (define-anyof-operand + (name (.sym dst32-basic-Prefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with no additional fields")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-Rn-direct-Prefixed- xmode) + (.sym dst32-An-direct-Prefixed- xmode) + (.sym dst32-An-indirect-Prefixed- xmode) + ) + ) + ) +) + +(dst32-basic-operand QI) +(dst32-basic-operand HI) +(dst32-basic-operand SI) + +;------------------------------------------------------------- +; Destination operands with possible additional fields at offset 16 bits +;------------------------------------------------------------- + +(define-pmacro (dst16-16-operand xmode) + (begin + (define-anyof-operand + (name (.sym dst16-16- xmode)) + (comment (.str "m16c destination operand of size " xmode " with additional fields at offset 16")) + (attrs (machine 16)) + (mode xmode) + (choices + (.sym dst16-Rn-direct- xmode) + (.sym dst16-An-direct- xmode) + (.sym dst16-An-indirect- xmode) + (.sym dst16-16-8-An-relative- xmode) + (.sym dst16-16-16-An-relative- xmode) + (.sym dst16-16-8-SB-relative- xmode) + (.sym dst16-16-16-SB-relative- xmode) + (.sym dst16-16-8-FB-relative- xmode) + (.sym dst16-16-16-absolute- xmode) + ) + ) + (define-anyof-operand + (name (.sym dst16-16-8- xmode)) + (comment (.str "m16c destination operand of size " xmode " with additional fields at offset 16")) + (attrs (machine 16)) + (mode xmode) + (choices + (.sym dst16-16-8-An-relative- xmode) + (.sym dst16-16-8-SB-relative- xmode) + (.sym dst16-16-8-FB-relative- xmode) + ) + ) + (define-anyof-operand + (name (.sym dst16-16-16- xmode)) + (comment (.str "m16c destination operand of size " xmode " with additional fields at offset 16")) + (attrs (machine 16)) + (mode xmode) + (choices + (.sym dst16-16-16-An-relative- xmode) + (.sym dst16-16-16-SB-relative- xmode) + (.sym dst16-16-16-absolute- xmode) + ) + ) + (define-anyof-operand + (name (.sym dst16-16-16sa- xmode)) + (comment (.str "m16c destination operand of size " xmode " with additional fields at offset 16")) + (attrs (machine 16)) + (mode xmode) + (choices + (.sym dst16-16-16-SB-relative- xmode) + (.sym dst16-16-16-absolute- xmode) + ) + ) + (define-anyof-operand + (name (.sym dst16-16-20ar- xmode)) + (comment (.str "m16c destination operand of size " xmode " with additional fields at offset 16")) + (attrs (machine 16)) + (mode xmode) + (choices + (.sym dst16-16-20-An-relative- xmode) + ) + ) + ) +) + +(dst16-16-operand QI) +(dst16-16-operand HI) +(dst16-16-operand SI) + +(define-anyof-operand + (name dst16-16-Ext-QI) + (comment "m16c destination operand of size QI for 'ext' insns with additional fields at offset 16") + (attrs (machine 16)) + (mode QI) + (choices + dst16-Rn-direct-Ext-QI + dst16-An-indirect-Ext-QI + dst16-16-8-An-relative-Ext-QI + dst16-16-16-An-relative-Ext-QI + dst16-16-8-SB-relative-Ext-QI + dst16-16-16-SB-relative-Ext-QI + dst16-16-8-FB-relative-Ext-QI + dst16-16-16-absolute-Ext-QI + ) +) + +(define-derived-operand + (name dst16-An-indirect-Mova-HI) + (comment "m16c addressof An indirect destination HI") + (attrs (ISA m16c)) + (mode HI) + (args (Dst16An)) + (syntax "[$Dst16An]") + (base-ifield f-12-4) + (encoding (+ (f-12-2 1) (f-14-1 1) Dst16An)) + (ifield-assertion + (andif (eq f-12-2 1) (eq f-14-1 1))) + (getter Dst16An) + (setter (nop)) + ) + +(define-derived-operand + (name dst16-16-8-An-relative-Mova-HI) + (comment + "m16c addressof dsp:8[An] relative destination HI") + (attrs (ISA m16c)) + (mode HI) + (args (Dst16An Dsp-16-u8)) + (syntax "${Dsp-16-u8}[$Dst16An]") + (base-ifield f-12-4) + (encoding + (+ (f-12-2 2) (f-14-1 0) Dsp-16-u8 Dst16An)) + (ifield-assertion + (andif (eq f-12-2 2) (eq f-14-1 0))) + (getter (add Dsp-16-u8 Dst16An)) + (setter (nop)) +) +(define-derived-operand + (name dst16-16-16-An-relative-Mova-HI) + (comment + "m16c addressof dsp:16[An] relative destination HI") + (attrs (ISA m16c)) + (mode HI) + (args (Dst16An Dsp-16-u16)) + (syntax "${Dsp-16-u16}[$Dst16An]") + (base-ifield f-12-4) + (encoding + (+ (f-12-2 3) (f-14-1 0) Dsp-16-u16 Dst16An)) + (ifield-assertion + (andif (eq f-12-2 3) (eq f-14-1 0))) + (getter (add Dsp-16-u16 Dst16An)) + (setter (nop)) + ) +(define-derived-operand + (name dst16-16-8-SB-relative-Mova-HI) + (comment + "m16c addressof dsp:8[sb] relative destination HI") + (attrs (ISA m16c)) + (mode HI) + (args (Dsp-16-u8)) + (syntax "${Dsp-16-u8}[sb]") + (base-ifield f-12-4) + (encoding (+ (f-12-4 10) Dsp-16-u8)) + (ifield-assertion (eq f-12-4 10)) + (getter (add Dsp-16-u8 (reg h-sb))) + (setter (nop)) +) +(define-derived-operand + (name dst16-16-16-SB-relative-Mova-HI) + (comment + "m16c addressof dsp:16[sb] relative destination HI") + (attrs (ISA m16c)) + (mode HI) + (args (Dsp-16-u16)) + (syntax "${Dsp-16-u16}[sb]") + (base-ifield f-12-4) + (encoding (+ (f-12-4 14) Dsp-16-u16)) + (ifield-assertion (eq f-12-4 14)) + (getter (add Dsp-16-u16 (reg h-sb))) + (setter (nop)) + ) +(define-derived-operand + (name dst16-16-8-FB-relative-Mova-HI) + (comment + "m16c addressof dsp:8[fb] relative destination HI") + (attrs (ISA m16c)) + (mode HI) + (args (Dsp-16-s8)) + (syntax "${Dsp-16-s8}[fb]") + (base-ifield f-12-4) + (encoding (+ (f-12-4 11) Dsp-16-s8)) + (ifield-assertion (eq f-12-4 11)) + (getter (add Dsp-16-s8 (reg h-fb))) + (setter (nop)) + ) +(define-derived-operand + (name dst16-16-16-absolute-Mova-HI) + (comment "m16c addressof absolute address HI") + (attrs (ISA m16c)) + (mode HI) + (args (Dsp-16-u16)) + (syntax "${Dsp-16-u16}") + (base-ifield f-12-4) + (encoding (+ (f-12-4 15) Dsp-16-u16)) + (ifield-assertion (eq f-12-4 15)) + (getter Dsp-16-u16) + (setter (nop)) + ) + +(define-anyof-operand + (name dst16-16-Mova-HI) + (comment "m16c addressof destination operand of size HI with additional fields at offset 16") + (attrs (machine 16)) + (mode HI) + (choices + dst16-An-indirect-Mova-HI + dst16-16-8-An-relative-Mova-HI + dst16-16-16-An-relative-Mova-HI + dst16-16-8-SB-relative-Mova-HI + dst16-16-16-SB-relative-Mova-HI + dst16-16-8-FB-relative-Mova-HI + dst16-16-16-absolute-Mova-HI + ) +) + +(define-derived-operand + (name dst32-An-indirect-Unprefixed-Mova-SI) + (comment "m32c addressof An indirect destination SI") + (attrs (ISA m32c)) + (mode SI) + (args (Dst32AnUnprefixed)) + (syntax "[$Dst32AnUnprefixed]") + (base-ifield f-4-6) + (encoding + (+ (f-4-3 0) (f-8-1 0) Dst32AnUnprefixed)) + (ifield-assertion + (andif (eq f-4-3 0) (eq f-8-1 0))) + (getter Dst32AnUnprefixed) + (setter (nop)) + ) + +(define-derived-operand + (name dst32-16-8-An-relative-Unprefixed-Mova-SI) + (comment "m32c addressof dsp:8[An] relative destination SI") + (attrs (ISA m32c)) + (mode SI) + (args (Dst32AnUnprefixed Dsp-16-u8)) + (syntax "${Dsp-16-u8}[$Dst32AnUnprefixed]") + (base-ifield f-4-6) + (encoding + (+ (f-4-3 1) + (f-8-1 0) + Dsp-16-u8 + Dst32AnUnprefixed)) + (ifield-assertion + (andif (eq f-4-3 1) (eq f-8-1 0))) + (getter (add Dsp-16-u8 Dst32AnUnprefixed)) + (setter (nop)) +) + +(define-derived-operand + (name dst32-16-16-An-relative-Unprefixed-Mova-SI) + (comment + "m32c addressof dsp:16[An] relative destination SI") + (attrs (ISA m32c)) + (mode SI) + (args (Dst32AnUnprefixed Dsp-16-u16)) + (syntax "${Dsp-16-u16}[$Dst32AnUnprefixed]") + (base-ifield f-4-6) + (encoding + (+ (f-4-3 2) + (f-8-1 0) + Dsp-16-u16 + Dst32AnUnprefixed)) + (ifield-assertion + (andif (eq f-4-3 2) (eq f-8-1 0))) + (getter (add Dsp-16-u16 Dst32AnUnprefixed)) + (setter (nop)) + ) + +(define-derived-operand + (name dst32-16-24-An-relative-Unprefixed-Mova-SI) + (comment "addressof m32c dsp:16[An] relative destination SI") + (attrs (ISA m32c)) + (mode SI) + (args (Dst32AnUnprefixed Dsp-16-u24)) + (syntax "${Dsp-16-u24}[$Dst32AnUnprefixed]") + (base-ifield f-4-6) + (encoding + (+ (f-4-3 3) + (f-8-1 0) + Dsp-16-u24 + Dst32AnUnprefixed)) + (ifield-assertion + (andif (eq f-4-3 3) (eq f-8-1 0))) + (getter (add Dsp-16-u24 Dst32AnUnprefixed)) + (setter (nop)) + ) + +(define-derived-operand + (name dst32-16-8-SB-relative-Unprefixed-Mova-SI) + (comment "m32c addressof dsp:8[sb] relative destination SI") + (attrs (ISA m32c)) + (mode SI) + (args (Dsp-16-u8)) + (syntax "${Dsp-16-u8}[sb]") + (base-ifield f-4-6) + (encoding (+ (f-4-3 1) (f-8-2 2) Dsp-16-u8)) + (ifield-assertion + (andif (eq f-4-3 1) (eq f-8-2 2))) + (getter (add Dsp-16-u8 (reg h-sb))) + (setter (nop)) + ) + +(define-derived-operand + (name dst32-16-16-SB-relative-Unprefixed-Mova-SI) + (comment "m32c addressof dsp:16[sb] relative destination SI") + (attrs (ISA m32c)) + (mode SI) + (args (Dsp-16-u16)) + (syntax "${Dsp-16-u16}[sb]") + (base-ifield f-4-6) + (encoding (+ (f-4-3 2) (f-8-2 2) Dsp-16-u16)) + (ifield-assertion + (andif (eq f-4-3 2) (eq f-8-2 2))) + (getter (add Dsp-16-u16 (reg h-sb))) + (setter (nop)) + ) + +(define-derived-operand + (name dst32-16-8-FB-relative-Unprefixed-Mova-SI) + (comment "m32c addressof dsp:8[fb] relative destination SI") + (attrs (ISA m32c)) + (mode SI) + (args (Dsp-16-s8)) + (syntax "${Dsp-16-s8}[fb]") + (base-ifield f-4-6) + (encoding (+ (f-4-3 1) (f-8-2 3) Dsp-16-s8)) + (ifield-assertion + (andif (eq f-4-3 1) (eq f-8-2 3))) + (getter (add Dsp-16-s8 (reg h-fb))) + (setter (nop)) + ) + +(define-derived-operand + (name dst32-16-16-FB-relative-Unprefixed-Mova-SI) + (comment "m32c addressof dsp:16[fb] relative destination SI") + (attrs (ISA m32c)) + (mode SI) + (args (Dsp-16-s16)) + (syntax "${Dsp-16-s16}[fb]") + (base-ifield f-4-6) + (encoding (+ (f-4-3 2) (f-8-2 3) Dsp-16-s16)) + (ifield-assertion + (andif (eq f-4-3 2) (eq f-8-2 3))) + (getter (add Dsp-16-s16 (reg h-fb))) + (setter (nop)) + ) + +(define-derived-operand + (name dst32-16-16-absolute-Unprefixed-Mova-SI) + (comment "m32c addressof absolute address SI") (attrs (ISA m32c)) + (mode SI) + (args (Dsp-16-u16)) + (syntax "${Dsp-16-u16}") + (base-ifield f-4-6) + (encoding (+ (f-4-3 3) (f-8-2 3) Dsp-16-u16)) + (ifield-assertion + (andif (eq f-4-3 3) (eq f-8-2 3))) + (getter Dsp-16-u16) + (setter (nop)) + ) + +(define-derived-operand + (name dst32-16-24-absolute-Unprefixed-Mova-SI) + (comment "m32c addressof absolute address SI") (attrs (ISA m32c)) + (mode SI) + (args (Dsp-16-u24)) + (syntax "${Dsp-16-u24}") + (base-ifield f-4-6) + (encoding (+ (f-4-3 3) (f-8-2 2) Dsp-16-u24)) + (ifield-assertion + (andif (eq f-4-3 3) (eq f-8-2 2))) + (getter Dsp-16-u24) + (setter (nop)) + ) + +(define-anyof-operand + (name dst32-16-Unprefixed-Mova-SI) + (comment + "m32c addressof destination operand of size SI with additional fields at offset 16") + (attrs (ISA m32c)) + (mode SI) + (choices + dst32-An-indirect-Unprefixed-Mova-SI + dst32-16-8-An-relative-Unprefixed-Mova-SI + dst32-16-16-An-relative-Unprefixed-Mova-SI + dst32-16-24-An-relative-Unprefixed-Mova-SI + dst32-16-8-SB-relative-Unprefixed-Mova-SI + dst32-16-16-SB-relative-Unprefixed-Mova-SI + dst32-16-8-FB-relative-Unprefixed-Mova-SI + dst32-16-16-FB-relative-Unprefixed-Mova-SI + dst32-16-16-absolute-Unprefixed-Mova-SI + dst32-16-24-absolute-Unprefixed-Mova-SI)) + +(define-pmacro (dst32-16-operand xmode) + (begin + (define-anyof-operand + (name (.sym dst32-16-Unprefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 16")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-Rn-direct-Unprefixed- xmode) + (.sym dst32-An-direct-Unprefixed- xmode) + (.sym dst32-An-indirect-Unprefixed- xmode) + (.sym dst32-16-8-An-relative-Unprefixed- xmode) + (.sym dst32-16-16-An-relative-Unprefixed- xmode) + (.sym dst32-16-24-An-relative-Unprefixed- xmode) + (.sym dst32-16-8-SB-relative-Unprefixed- xmode) + (.sym dst32-16-16-SB-relative-Unprefixed- xmode) + (.sym dst32-16-8-FB-relative-Unprefixed- xmode) + (.sym dst32-16-16-FB-relative-Unprefixed- xmode) + (.sym dst32-16-16-absolute-Unprefixed- xmode) + (.sym dst32-16-24-absolute-Unprefixed- xmode) + ) + ) + (define-anyof-operand + (name (.sym dst32-16-8-Unprefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 16")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-16-8-An-relative-Unprefixed- xmode) + (.sym dst32-16-8-SB-relative-Unprefixed- xmode) + (.sym dst32-16-8-FB-relative-Unprefixed- xmode) + ) + ) + (define-anyof-operand + (name (.sym dst32-16-16-Unprefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 16")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-16-16-An-relative-Unprefixed- xmode) + (.sym dst32-16-16-SB-relative-Unprefixed- xmode) + (.sym dst32-16-16-FB-relative-Unprefixed- xmode) + (.sym dst32-16-16-absolute-Unprefixed- xmode) + ) + ) + (define-anyof-operand + (name (.sym dst32-16-16sa-Unprefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 16")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-16-16-SB-relative-Unprefixed- xmode) + (.sym dst32-16-16-FB-relative-Unprefixed- xmode) + (.sym dst32-16-16-absolute-Unprefixed- xmode) + ) + ) + (define-anyof-operand + (name (.sym dst32-16-24-Unprefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 16")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-16-24-An-relative-Unprefixed- xmode) + (.sym dst32-16-24-absolute-Unprefixed- xmode) + ) + ) + ) +) + +(dst32-16-operand QI) +(dst32-16-operand HI) +(dst32-16-operand SI) + +(define-pmacro (dst32-16-Ext-operand smode dmode) + (begin + (define-anyof-operand + (name (.sym dst32-16-ExtUnprefixed- smode)) + (comment (.str "m32c destination operand of size " smode " with additional fields at offset 16")) + (attrs (machine 32)) + (mode dmode) + (choices + (.sym dst32-Rn-direct-ExtUnprefixed- smode) + (.sym dst32-An-direct-Unprefixed- dmode) ; ExtUnprefixed mode not required for this operand -- use the normal dmode version + (.sym dst32-An-indirect-ExtUnprefixed- smode) + (.sym dst32-16-8-An-relative-ExtUnprefixed- smode) + (.sym dst32-16-16-An-relative-ExtUnprefixed- smode) + (.sym dst32-16-24-An-relative-ExtUnprefixed- smode) + (.sym dst32-16-8-SB-relative-ExtUnprefixed- smode) + (.sym dst32-16-16-SB-relative-ExtUnprefixed- smode) + (.sym dst32-16-8-FB-relative-ExtUnprefixed- smode) + (.sym dst32-16-16-FB-relative-ExtUnprefixed- smode) + (.sym dst32-16-16-absolute-ExtUnprefixed- smode) + (.sym dst32-16-24-absolute-ExtUnprefixed- smode) + ) + ) + ) +) + +(dst32-16-Ext-operand QI HI) +(dst32-16-Ext-operand HI SI) + +(define-anyof-operand + (name dst32-16-Unprefixed-Mulex-HI) + (comment "m32c destination operand of size HI with additional fields at offset 16") + (attrs (machine 32)) + (mode HI) + (choices + dst32-R3-direct-Unprefixed-HI + dst32-An-direct-Unprefixed-HI + dst32-An-indirect-Unprefixed-HI + dst32-16-8-An-relative-Unprefixed-HI + dst32-16-16-An-relative-Unprefixed-HI + dst32-16-24-An-relative-Unprefixed-HI + dst32-16-8-SB-relative-Unprefixed-HI + dst32-16-16-SB-relative-Unprefixed-HI + dst32-16-8-FB-relative-Unprefixed-HI + dst32-16-16-FB-relative-Unprefixed-HI + dst32-16-16-absolute-Unprefixed-HI + dst32-16-24-absolute-Unprefixed-HI + ) +) +;------------------------------------------------------------- +; Destination operands with possible additional fields at offset 24 bits +;------------------------------------------------------------- + +(define-pmacro (dst16-24-operand xmode) + (begin + (define-anyof-operand + (name (.sym dst16-24- xmode)) + (comment (.str "m16c destination operand of size " xmode " with additional fields at offset 24")) + (attrs (machine 16)) + (mode xmode) + (choices + (.sym dst16-Rn-direct- xmode) + (.sym dst16-An-direct- xmode) + (.sym dst16-An-indirect- xmode) + (.sym dst16-24-8-An-relative- xmode) + (.sym dst16-24-16-An-relative- xmode) + (.sym dst16-24-8-SB-relative- xmode) + (.sym dst16-24-16-SB-relative- xmode) + (.sym dst16-24-8-FB-relative- xmode) + (.sym dst16-24-16-absolute- xmode) + ) + ) + ) +) + +(dst16-24-operand QI) +(dst16-24-operand HI) + +(define-pmacro (dst32-24-operand xmode) + (begin + (define-anyof-operand + (name (.sym dst32-24-Unprefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 24")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-Rn-direct-Unprefixed- xmode) + (.sym dst32-An-direct-Unprefixed- xmode) + (.sym dst32-An-indirect-Unprefixed- xmode) + (.sym dst32-24-8-An-relative-Unprefixed- xmode) + (.sym dst32-24-16-An-relative-Unprefixed- xmode) + (.sym dst32-24-24-An-relative-Unprefixed- xmode) + (.sym dst32-24-8-SB-relative-Unprefixed- xmode) + (.sym dst32-24-16-SB-relative-Unprefixed- xmode) + (.sym dst32-24-8-FB-relative-Unprefixed- xmode) + (.sym dst32-24-16-FB-relative-Unprefixed- xmode) + (.sym dst32-24-16-absolute-Unprefixed- xmode) + (.sym dst32-24-24-absolute-Unprefixed- xmode) + ) + ) + (define-anyof-operand + (name (.sym dst32-24-Prefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 24")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-Rn-direct-Prefixed- xmode) + (.sym dst32-An-direct-Prefixed- xmode) + (.sym dst32-An-indirect-Prefixed- xmode) + (.sym dst32-24-8-An-relative-Prefixed- xmode) + (.sym dst32-24-16-An-relative-Prefixed- xmode) + (.sym dst32-24-24-An-relative-Prefixed- xmode) + (.sym dst32-24-8-SB-relative-Prefixed- xmode) + (.sym dst32-24-16-SB-relative-Prefixed- xmode) + (.sym dst32-24-8-FB-relative-Prefixed- xmode) + (.sym dst32-24-16-FB-relative-Prefixed- xmode) + (.sym dst32-24-16-absolute-Prefixed- xmode) + (.sym dst32-24-24-absolute-Prefixed- xmode) + ) + ) + (define-anyof-operand + (name (.sym dst32-24-8-Prefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 24")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-24-8-An-relative-Prefixed- xmode) + (.sym dst32-24-8-SB-relative-Prefixed- xmode) + (.sym dst32-24-8-FB-relative-Prefixed- xmode) + ) + ) + (define-anyof-operand + (name (.sym dst32-24-16-Prefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 24")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-24-16-An-relative-Prefixed- xmode) + (.sym dst32-24-16-SB-relative-Prefixed- xmode) + (.sym dst32-24-16-FB-relative-Prefixed- xmode) + (.sym dst32-24-16-absolute-Prefixed- xmode) + ) + ) + (define-anyof-operand + (name (.sym dst32-24-24-Prefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 24")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-24-24-An-relative-Prefixed- xmode) + (.sym dst32-24-24-absolute-Prefixed- xmode) + ) + ) +; (define-anyof-operand +; (name (.sym dst32-24-indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 24")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym dst32-An-indirect-indirect- xmode) +; (.sym dst32-24-8-An-relative-indirect- xmode) +; (.sym dst32-24-16-An-relative-indirect- xmode) +; (.sym dst32-24-24-An-relative-indirect- xmode) +; (.sym dst32-24-8-SB-relative-indirect- xmode) +; (.sym dst32-24-16-SB-relative-indirect- xmode) +; (.sym dst32-24-8-FB-relative-indirect- xmode) +; (.sym dst32-24-16-FB-relative-indirect- xmode) +; ) +; ) +; (define-anyof-operand +; (name (.sym dst32-basic-indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " with no additional fields")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym dst32-An-indirect-indirect- xmode) +; ) +; ) +; (define-anyof-operand +; (name (.sym dst32-24-8-indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 24")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym dst32-24-8-An-relative-indirect- xmode) +; (.sym dst32-24-8-SB-relative-indirect- xmode) +; (.sym dst32-24-8-FB-relative-indirect- xmode) +; ) +; ) +; (define-anyof-operand +; (name (.sym dst32-24-16-indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 24")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym dst32-24-16-An-relative-indirect- xmode) +; (.sym dst32-24-16-SB-relative-indirect- xmode) +; (.sym dst32-24-16-FB-relative-indirect- xmode) +; ) +; ) +; (define-anyof-operand +; (name (.sym dst32-24-24-indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 24")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym dst32-24-24-An-relative-indirect- xmode) +; ) +; ) +; (define-anyof-operand +; (name (.sym dst32-24-absolute-indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " absolute indirect")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym dst32-24-16-absolute-indirect-derived- xmode) +; (.sym dst32-24-24-absolute-indirect-derived- xmode) +; ) +; ) +; (define-anyof-operand +; (name (.sym dst32-24-16-absolute-indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " absolute indirect")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym dst32-24-16-absolute-indirect-derived- xmode) +; ) +; ) +; (define-anyof-operand +; (name (.sym dst32-24-24-absolute-indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " absolute indirect")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym dst32-24-24-absolute-indirect-derived- xmode) +; ) +; ) + ) +) + +(dst32-24-operand QI) +(dst32-24-operand HI) +(dst32-24-operand SI) + +;------------------------------------------------------------- +; Destination operands with possible additional fields at offset 32 bits +;------------------------------------------------------------- + +(define-pmacro (dst16-32-operand xmode) + (begin + (define-anyof-operand + (name (.sym dst16-32- xmode)) + (comment (.str "m16c destination operand of size " xmode " with additional fields at offset 32")) + (attrs (machine 16)) + (mode xmode) + (choices + (.sym dst16-Rn-direct- xmode) + (.sym dst16-An-direct- xmode) + (.sym dst16-An-indirect- xmode) + (.sym dst16-32-8-An-relative- xmode) + (.sym dst16-32-16-An-relative- xmode) + (.sym dst16-32-8-SB-relative- xmode) + (.sym dst16-32-16-SB-relative- xmode) + (.sym dst16-32-8-FB-relative- xmode) + (.sym dst16-32-16-absolute- xmode) + ) + ) + ) +) +(dst16-32-operand QI) +(dst16-32-operand HI) + +; This macro actually handles operands at offset 32, 40 and 48 bits +(define-pmacro (dst32-32plus-operand offset xmode) + (begin + (define-anyof-operand + (name (.sym dst32- offset -Unprefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 32")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-Rn-direct-Unprefixed- xmode) + (.sym dst32-An-direct-Unprefixed- xmode) + (.sym dst32-An-indirect-Unprefixed- xmode) + (.sym dst32- offset -8-An-relative-Unprefixed- xmode) + (.sym dst32- offset -16-An-relative-Unprefixed- xmode) + (.sym dst32- offset -24-An-relative-Unprefixed- xmode) + (.sym dst32- offset -8-SB-relative-Unprefixed- xmode) + (.sym dst32- offset -16-SB-relative-Unprefixed- xmode) + (.sym dst32- offset -8-FB-relative-Unprefixed- xmode) + (.sym dst32- offset -16-FB-relative-Unprefixed- xmode) + (.sym dst32- offset -16-absolute-Unprefixed- xmode) + (.sym dst32- offset -24-absolute-Unprefixed- xmode) + ) + ) + (define-anyof-operand + (name (.sym dst32- offset -Prefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 32")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-Rn-direct-Prefixed- xmode) + (.sym dst32-An-direct-Prefixed- xmode) + (.sym dst32-An-indirect-Prefixed- xmode) + (.sym dst32- offset -8-An-relative-Prefixed- xmode) + (.sym dst32- offset -16-An-relative-Prefixed- xmode) + (.sym dst32- offset -24-An-relative-Prefixed- xmode) + (.sym dst32- offset -8-SB-relative-Prefixed- xmode) + (.sym dst32- offset -16-SB-relative-Prefixed- xmode) + (.sym dst32- offset -8-FB-relative-Prefixed- xmode) + (.sym dst32- offset -16-FB-relative-Prefixed- xmode) + (.sym dst32- offset -16-absolute-Prefixed- xmode) + (.sym dst32- offset -24-absolute-Prefixed- xmode) + ) + ) +; (define-anyof-operand +; (name (.sym dst32- offset -indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 32")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym dst32-An-indirect-indirect- xmode) +; (.sym dst32- offset -8-An-relative-indirect- xmode) +; (.sym dst32- offset -16-An-relative-indirect- xmode) +; (.sym dst32- offset -24-An-relative-indirect- xmode) +; (.sym dst32- offset -8-SB-relative-indirect- xmode) +; (.sym dst32- offset -16-SB-relative-indirect- xmode) +; (.sym dst32- offset -8-FB-relative-indirect- xmode) +; (.sym dst32- offset -16-FB-relative-indirect- xmode) +; ) +; ) +; (define-anyof-operand +; (name (.sym dst32- offset -absolute-indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " absolute indirect")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym dst32- offset -16-absolute-indirect-derived- xmode) +; (.sym dst32- offset -24-absolute-indirect-derived- xmode) +; ) +; ) + ) +) + +(dst32-32plus-operand 32 QI) +(dst32-32plus-operand 32 HI) +(dst32-32plus-operand 32 SI) +(dst32-32plus-operand 40 QI) +(dst32-32plus-operand 40 HI) +(dst32-32plus-operand 40 SI) + +;------------------------------------------------------------- +; Destination operands with possible additional fields at offset 48 bits +;------------------------------------------------------------- + +(define-pmacro (dst32-48-operand offset xmode) + (begin + (define-anyof-operand + (name (.sym dst32- offset -Prefixed- xmode)) + (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 32")) + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-Rn-direct-Prefixed- xmode) + (.sym dst32-An-direct-Prefixed- xmode) + (.sym dst32-An-indirect-Prefixed- xmode) + (.sym dst32- offset -8-An-relative-Prefixed- xmode) + (.sym dst32- offset -16-An-relative-Prefixed- xmode) + (.sym dst32- offset -24-An-relative-Prefixed- xmode) + (.sym dst32- offset -8-SB-relative-Prefixed- xmode) + (.sym dst32- offset -16-SB-relative-Prefixed- xmode) + (.sym dst32- offset -8-FB-relative-Prefixed- xmode) + (.sym dst32- offset -16-FB-relative-Prefixed- xmode) + (.sym dst32- offset -16-absolute-Prefixed- xmode) + (.sym dst32- offset -24-absolute-Prefixed- xmode) + ) + ) +; (define-anyof-operand +; (name (.sym dst32- offset -indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " with additional fields at offset 32")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym dst32-An-indirect-indirect- xmode) +; (.sym dst32- offset -8-An-relative-indirect- xmode) +; (.sym dst32- offset -16-An-relative-indirect- xmode) +; (.sym dst32- offset -24-An-relative-indirect- xmode) +; (.sym dst32- offset -8-SB-relative-indirect- xmode) +; (.sym dst32- offset -16-SB-relative-indirect- xmode) +; (.sym dst32- offset -8-FB-relative-indirect- xmode) +; (.sym dst32- offset -16-FB-relative-indirect- xmode) +; ) +; ) +; (define-anyof-operand +; (name (.sym dst32- offset -absolute-indirect- xmode)) +; (comment (.str "m32c destination operand of size " xmode " absolute indirect")) +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym dst32- offset -16-absolute-indirect-derived- xmode) +; (.sym dst32- offset -24-absolute-indirect-derived- xmode) +; ) +; ) + ) +) + +(dst32-48-operand 48 QI) +(dst32-48-operand 48 HI) +(dst32-48-operand 48 SI) + +;------------------------------------------------------------- +; Bit operands for m16c +;------------------------------------------------------------- + +(define-pmacro (bit16-operand offset) + (begin + (define-anyof-operand + (name (.sym bit16- offset)) + (comment (.str "m16c bit operand with possible additional fields at offset 24")) + (attrs (machine 16)) + (mode BI) + (choices + bit16-Rn-direct + bit16-An-direct + bit16-An-indirect + (.sym bit16- offset -8-An-relative) + (.sym bit16- offset -16-An-relative) + (.sym bit16- offset -8-SB-relative) + (.sym bit16- offset -16-SB-relative) + (.sym bit16- offset -8-FB-relative) + (.sym bit16- offset -16-absolute) + ) + ) + (define-anyof-operand + (name (.sym bit16- offset -basic)) + (comment (.str "m16c bit operand with no additional fields")) + (attrs (machine 16)) + (mode BI) + (choices + bit16-An-indirect + ) + ) + (define-anyof-operand + (name (.sym bit16- offset -8)) + (comment (.str "m16c bit operand with possible additional fields at offset 24")) + (attrs (machine 16)) + (mode BI) + (choices + bit16-Rn-direct + bit16-An-direct + (.sym bit16- offset -8-An-relative) + (.sym bit16- offset -8-SB-relative) + (.sym bit16- offset -8-FB-relative) + ) + ) + (define-anyof-operand + (name (.sym bit16- offset -16)) + (comment (.str "m16c bit operand with possible additional fields at offset 24")) + (attrs (machine 16)) + (mode BI) + (choices + (.sym bit16- offset -16-An-relative) + (.sym bit16- offset -16-SB-relative) + (.sym bit16- offset -16-absolute) + ) + ) + ) +) + +(bit16-operand 16) + +;------------------------------------------------------------- +; Bit operands for m32c +;------------------------------------------------------------- + +(define-pmacro (bit32-operand offset group) + (begin + (define-anyof-operand + (name (.sym bit32- offset - group)) + (comment (.str "m32c bit operand with possible additional fields at offset 24")) + (attrs (machine 32)) + (mode BI) + (choices + (.sym bit32-Rn-direct- group) + (.sym bit32-An-direct- group) + (.sym bit32-An-indirect- group) + (.sym bit32- offset -11-An-relative- group) + (.sym bit32- offset -19-An-relative- group) + (.sym bit32- offset -27-An-relative- group) + (.sym bit32- offset -11-SB-relative- group) + (.sym bit32- offset -19-SB-relative- group) + (.sym bit32- offset -11-FB-relative- group) + (.sym bit32- offset -19-FB-relative- group) + (.sym bit32- offset -19-absolute- group) + (.sym bit32- offset -27-absolute- group) + ) + ) + ) +) + +(bit32-operand 16 Unprefixed) +(bit32-operand 24 Prefixed) + +(define-anyof-operand + (name bit32-basic-Unprefixed) + (comment "m32c bit operand with no additional fields") + (attrs (machine 32)) + (mode BI) + (choices + bit32-Rn-direct-Unprefixed + bit32-An-direct-Unprefixed + bit32-An-indirect-Unprefixed + ) +) + +(define-anyof-operand + (name bit32-16-8-Unprefixed) + (comment "m32c bit operand with 8 bit additional fields") + (attrs (machine 32)) + (mode BI) + (choices + bit32-16-11-An-relative-Unprefixed + bit32-16-11-SB-relative-Unprefixed + bit32-16-11-FB-relative-Unprefixed + ) +) + +(define-anyof-operand + (name bit32-16-16-Unprefixed) + (comment "m32c bit operand with 16 bit additional fields") + (attrs (machine 32)) + (mode BI) + (choices + bit32-16-19-An-relative-Unprefixed + bit32-16-19-SB-relative-Unprefixed + bit32-16-19-FB-relative-Unprefixed + bit32-16-19-absolute-Unprefixed + ) +) + +(define-anyof-operand + (name bit32-16-24-Unprefixed) + (comment "m32c bit operand with 24 bit additional fields") + (attrs (machine 32)) + (mode BI) + (choices + bit32-16-27-An-relative-Unprefixed + bit32-16-27-absolute-Unprefixed + ) +) + +;------------------------------------------------------------- +; Operands for short format binary insns +;------------------------------------------------------------- + +(define-anyof-operand + (name src16-2-S) + (comment "m16c source operand of size QI for short format insns") + (attrs (machine 16)) + (mode QI) + (choices + src16-2-S-8-SB-relative-QI + src16-2-S-8-FB-relative-QI + src16-2-S-16-absolute-QI + ) +) + +(define-anyof-operand + (name src32-2-S-QI) + (comment "m32c source operand of size QI for short format insns") + (attrs (machine 32)) + (mode QI) + (choices + src32-2-S-8-SB-relative-QI + src32-2-S-8-FB-relative-QI + src32-2-S-16-absolute-QI + ) +) + +(define-anyof-operand + (name src32-2-S-HI) + (comment "m32c source operand of size QI for short format insns") + (attrs (machine 32)) + (mode HI) + (choices + src32-2-S-8-SB-relative-HI + src32-2-S-8-FB-relative-HI + src32-2-S-16-absolute-HI + ) +) + +(define-anyof-operand + (name Dst16-3-S-8) + (comment "m16c destination operand of size QI for short format insns") + (attrs (machine 16)) + (mode QI) + (choices + dst16-3-S-R0l-direct-QI + dst16-3-S-R0h-direct-QI + dst16-3-S-8-8-SB-relative-QI + dst16-3-S-8-8-FB-relative-QI + dst16-3-S-8-16-absolute-QI + ) +) + +(define-anyof-operand + (name Dst16-3-S-16) + (comment "m16c destination operand of size QI for short format insns") + (attrs (machine 16)) + (mode QI) + (choices + dst16-3-S-R0l-direct-QI + dst16-3-S-R0h-direct-QI + dst16-3-S-16-8-SB-relative-QI + dst16-3-S-16-8-FB-relative-QI + dst16-3-S-16-16-absolute-QI + ) +) + +(define-anyof-operand + (name srcdst16-r0l-r0h-S) + (comment "m16c r0l/r0h operand of size QI for short format insns") + (attrs (machine 16)) + (mode SI) + (choices + srcdst16-r0l-r0h-S-derived + ) +) + +(define-anyof-operand + (name dst32-2-S-basic-QI) + (comment "m32c r0l operand of size QI for short format binary insns") + (attrs (machine 32)) + (mode QI) + (choices + dst32-2-S-R0l-direct-QI + ) +) + +(define-anyof-operand + (name dst32-2-S-basic-HI) + (comment "m32c r0 operand of size HI for short format binary insns") + (attrs (machine 32)) + (mode HI) + (choices + dst32-2-S-R0-direct-HI + ) +) + +(define-pmacro (dst32-2-S-operands xmode) + (begin + (define-anyof-operand + (name (.sym dst32-2-S-8- xmode)) + (comment "m32c operand of size " xmode " for short format binary insns") + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-2-S-8-SB-relative- xmode) + (.sym dst32-2-S-8-FB-relative- xmode) + ) + ) + (define-anyof-operand + (name (.sym dst32-2-S-16- xmode)) + (comment "m32c operand of size " xmode " for short format binary insns") + (attrs (machine 32)) + (mode xmode) + (choices + (.sym dst32-2-S-16-absolute- xmode) + ) + ) +; (define-anyof-operand +; (name (.sym dst32-2-S-8-indirect- xmode)) +; (comment "m32c operand of size " xmode " for short format binary insns") +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym dst32-2-S-8-SB-relative-indirect- xmode) +; (.sym dst32-2-S-8-FB-relative-indirect- xmode) +; ) +; ) +; (define-anyof-operand +; (name (.sym dst32-2-S-absolute-indirect- xmode)) +; (comment "m32c operand of size " xmode " for short format binary insns") +; (attrs (machine 32)) +; (mode xmode) +; (choices +; (.sym dst32-2-S-16-absolute-indirect- xmode) +; ) +; ) + ) +) + +(dst32-2-S-operands QI) +(dst32-2-S-operands HI) +(dst32-2-S-operands SI) + +(define-anyof-operand + (name dst32-an-S) + (comment "m32c An operand for short format binary insns") + (attrs (machine 32)) + (mode HI) + (choices + dst32-1-S-A0-direct-HI + dst32-1-S-A1-direct-HI + ) +) + +(define-anyof-operand + (name bit16-11-S) + (comment "m16c bit operand for short format insns") + (attrs (machine 16)) + (mode BI) + (choices + bit16-11-SB-relative-S + ) +) + +(define-anyof-operand + (name Rn16-push-S-anyof) + (comment "m16c bit operand for short format insns") + (attrs (machine 16)) + (mode QI) + (choices + Rn16-push-S-derived + ) +) + +(define-anyof-operand + (name An16-push-S-anyof) + (comment "m16c bit operand for short format insns") + (attrs (machine 16)) + (mode HI) + (choices + An16-push-S-derived + ) +) + +;============================================================= +; Common macros for instruction definitions +; +(define-pmacro (set-z x) + (sequence () + (set zbit (zflag x))) + +) + +(define-pmacro (set-s x) + (sequence () + (set sbit (nflag x))) +) + +(define-pmacro (set-z-and-s x) + (sequence () + (set-z x) + (set-s x)) +) + +;============================================================= +; Unary insn macros +;------------------------------------------------------------- + +(define-pmacro (unary-insn-defn-g mach group mode wstr op encoding sem opg) + (dni (.sym op mach wstr - group) + (.str op wstr opg " dst" mach "-" group "-" mode) + ((machine mach) RL_1ADDR) + (.str op wstr opg " ${dst" mach "-" group "-" mode "}") + encoding + (sem mode (.sym dst mach - group - mode)) + ()) +) + +(define-pmacro (unary-insn-defn mach group mode wstr op encoding sem) + (unary-insn-defn-g mach group mode wstr op encoding sem "") +) + + +(define-pmacro (unary16-defn-g mode wstr wbit op opc1 opc2 opc3 sem opg) + (unary-insn-defn-g 16 16 mode wstr op + (+ opc1 opc2 (f-7-1 wbit) opc3 (.sym dst16-16- mode)) + sem opg) +) +(define-pmacro (unary16-defn mode wstr wbit op opc1 opc2 opc3 sem) + (unary-16-defn-g mode wstr wbit op opc1 opc2 opc3 sem "") +) + +(define-pmacro (unary32-defn-g mode wstr wbit op opc1 opc2 opc3 sem opg) + (begin + ; Multi insns are tried for assembly in the reverse order in which they appear here, so + ; define the absolute-indirect insns first in order to prevent them from being selected + ; when the mode is register-indirect +; (unary-insn-defn 32 24-absolute-indirect mode wstr op +; (+ (f-0-4 0) (f-4-4 9) (f-8-4 opc1) (f-15-1 wbit) (.sym dst32-24-absolute-indirect- mode) (f-18-2 opc2) (f-20-4 opc3)) +; sem) + (unary-insn-defn-g 32 16-Unprefixed mode wstr op + (+ (f-0-4 opc1) (f-7-1 wbit) (.sym dst32-16-Unprefixed- mode) (f-10-2 opc2) (f-12-4 opc3)) + sem opg) +; (unary-insn-defn 32 24-indirect mode wstr op +; (+ (f-0-4 0) (f-4-4 9) (f-8-4 opc1) (f-15-1 wbit) (.sym dst32-24-indirect- mode) (f-18-2 opc2) (f-20-4 opc3)) +; sem) + ) +) +(define-pmacro (unary32-defn mode wstr wbit op opc1 opc2 opc3 sem) + (unary32-defn-g mode wstr wbit op opc1 opc2 opc3 sem "") +) + +(define-pmacro (unary-insn-mach-g mach op opc1 opc2 opc3 sem opg) + (begin + (.apply (.sym unary mach -defn-g) (QI .b 0 op opc1 opc2 opc3 sem opg)) + (.apply (.sym unary mach -defn-g) (HI .w 1 op opc1 opc2 opc3 sem opg)) + ) +) +(define-pmacro (unary-insn-mach mach op opc1 opc2 opc3 sem) + (unary-insn-mach-g mach op opc1 opc2 opc3 sem "") +) + +(define-pmacro (unary-insn op opc16-1 opc16-2 opc16-3 opc32-1 opc32-2 opc32-3 sem) + (begin + (unary-insn-mach-g 16 op opc16-1 opc16-2 opc16-3 sem "") + (unary-insn-mach-g 32 op opc32-1 opc32-2 opc32-3 sem "") + ) +) + +(define-pmacro (unary-insn-g op opc16-1 opc16-2 opc16-3 opc32-1 opc32-2 opc32-3 sem) + (begin + (unary-insn-mach-g 16 op opc16-1 opc16-2 opc16-3 sem "$G") + (unary-insn-mach-g 32 op opc32-1 opc32-2 opc32-3 sem "$G") + ) +) + +;------------------------------------------------------------- +; Sign/zero extension macros +;------------------------------------------------------------- + +(define-pmacro (ext-insn-defn mach group smode dmode wstr op encoding sem) + (dni (.sym op mach wstr - group) + (.str op wstr " dst" mach "-" group "-" smode) + ((machine mach)) + (.str op wstr " ${dst" mach "-" group "-" smode "}") + encoding + (sem smode dmode (.sym dst mach - group - smode) (.sym dst mach - group - smode)) + ()) +) + +(define-pmacro (ext16-defn smode dmode wstr wbit op opc1 opc2 opc3 sem) + (ext-insn-defn 16 16-Ext smode dmode wstr op + (+ opc1 opc2 (f-7-1 wbit) opc3 (.sym dst16-16-Ext- smode)) + sem) +) + +(define-pmacro (ext32-defn smode dmode wstr wbit op opc1 opc2 opc3 sem) + (ext-insn-defn 32 16-ExtUnprefixed smode dmode wstr op + (+ opc1 opc2 (f-7-1 wbit) opc3 (.sym dst32-16-ExtUnprefixed- smode)) + sem) +) + +(define-pmacro (ext32-binary-insn src-group dst-group op wstr encoding sem) + (dni (.sym op 32 wstr - src-group - dst-group) + (.str op 32 wstr " src32-" src-group "-QI,dst32-" dst-group "-HI") + ((machine 32)) + (.str op wstr " ${src32-" src-group "-QI},${dst32-" dst-group "-HI}") + encoding + (sem QI HI (.sym src32- src-group -QI) (.sym dst32 - dst-group -HI)) + ()) +) + +(define-pmacro (ext32-binary-defn op wstr opc1 opc2 sem) + (begin + (ext32-binary-insn basic-ExtPrefixed 24-Prefixed op wstr + (+ (f-0-4 0) (f-4-4 1) (f-8-1 opc1) (f-15-1 0) src32-basic-ExtPrefixed-QI dst32-24-Prefixed-HI (f-20-4 opc2)) + sem) + (ext32-binary-insn 24-24-Prefixed 48-Prefixed op wstr + (+ (f-0-4 0) (f-4-4 1) (f-8-1 opc1) (f-15-1 0) src32-24-24-Prefixed-QI dst32-48-Prefixed-HI (f-20-4 opc2)) + sem) + (ext32-binary-insn 24-16-Prefixed 40-Prefixed op wstr + (+ (f-0-4 0) (f-4-4 1) (f-8-1 opc1) (f-15-1 0) src32-24-16-Prefixed-QI dst32-40-Prefixed-HI (f-20-4 opc2)) + sem) + (ext32-binary-insn 24-8-Prefixed 32-Prefixed op wstr + (+ (f-0-4 0) (f-4-4 1) (f-8-1 opc1) (f-15-1 0) src32-24-8-Prefixed-QI dst32-32-Prefixed-HI (f-20-4 opc2)) + sem) + ) +) + +;============================================================= +; Binary Arithmetic macros +; +;------------------------------------------------------------- +;<arith>.size:S src2,r0[l] -- for m32c +;------------------------------------------------------------- + +(define-pmacro (binary-arith32-S-src2 op xmode wstr wbit opc1 opc2 sem) + (dni (.sym op 32 wstr .S-src2-r0- xmode) + (.str op 32 wstr ":S src2,r0[l]") + ((machine 32)) + (.str op wstr"$S ${src32-2-S-" xmode "},${Dst32R0" xmode "-S}") + (+ opc1 opc2 (.sym src32-2-S- xmode) (f-7-1 wbit)) + (sem xmode (.sym src32-2-S- xmode) (.sym Dst32R0 xmode -S)) + ()) +) + +;------------------------------------------------------------- +;<arith>.b:S src2,r0l/r0h -- for m16c +;------------------------------------------------------------- + +(define-pmacro (binary-arith16-b-S-src2 op opc1 opc2 sem) + (begin + (dni (.sym op 16 .b.S-src2) + (.str op ".b:S src2,r0[lh]") + ((machine 16)) + (.str op ".b$S ${src16-2-S},${Dst16RnQI-S}") + (+ opc1 opc2 Dst16RnQI-S src16-2-S) + (sem QI src16-2-S Dst16RnQI-S) + ()) + (dni (.sym op 16 .b.S-r0l-r0h) + (.str op ".b:S r0l/r0h") + ((machine 16)) + (.str op ".b$S ${srcdst16-r0l-r0h-S}") + (+ opc1 opc2 srcdst16-r0l-r0h-S) + (if (eq srcdst16-r0l-r0h-S 0) + (sem QI R0h R0l) + (sem QI R0l R0h)) + ()) + ) +) + +;------------------------------------------------------------- +;<arith>.b:S #imm8,dst3 -- for m16c +;------------------------------------------------------------- + +(define-pmacro (binary-arith16-b-S-imm8-dst3 op sz opc1 opc2 sem) + (dni (.sym op 16 .b.S-imm8-dst3) + (.str op sz ":S imm8,dst3") + ((machine 16)) + (.str op sz "$S #${Imm-8-QI},${Dst16-3-S-16}") + (+ opc1 opc2 Dst16-3-S-16 Imm-8-QI) + (sem QI Imm-8-QI Dst16-3-S-16) + ()) +) + +;------------------------------------------------------------- +;<arith>.size:Q #imm4,sp -- for m16c +;------------------------------------------------------------- + +(define-pmacro (binary-arith16-Q-sp op opc1 opc2 opc3 sem) + (dni (.sym op 16 -wQ-sp) + (.str op ".w:q #imm4,sp") + ((machine 16)) + (.str op ".w$Q #${Imm-12-s4},sp") + (+ opc1 opc2 opc3 Imm-12-s4) + (sem QI Imm-12-s4 sp) + ()) +) + +;------------------------------------------------------------- +;<arith>.size:G #imm,sp -- for m16c +;------------------------------------------------------------- + +(define-pmacro (binary-arith16-G-sp-defn mode wstr wbit op opc1 opc2 opc3 opc4 sem) + (dni (.sym op 16 wstr - G-sp) + (.str op wstr " imm-sp " mode) + ((machine 16)) + (.str op wstr "$G #${Imm-16-" mode "},sp") + (+ opc1 opc2 (f-7-1 wbit) opc3 opc4 (.sym Imm-16- mode)) + (sem mode (.sym Imm-16- mode) sp) + ()) +) + +(define-pmacro (binary-arith16-G-sp op opc1 opc2 opc3 opc4 sem) + (begin + (binary-arith16-G-sp-defn QI .b 0 op opc1 opc2 opc3 opc4 sem) + (binary-arith16-G-sp-defn HI .w 1 op opc1 opc2 opc3 opc4 sem) + ) +) + +;------------------------------------------------------------- +;<arith>.size:G #imm,dst -- for m16c and m32c +;------------------------------------------------------------- + +(define-pmacro (binary-arith-imm-dst-defn mach src dstgroup dmode wstr op suffix encoding sem) + (dni (.sym op mach wstr - imm-G - dstgroup) + (.str op wstr " " mach "-imm-G-" dstgroup "-" dmode) + ((machine mach) RL_1ADDR) + (.str op wstr "$"suffix " #${" src "},${dst" mach "-" dstgroup "-" dmode "}") + encoding + (sem dmode src (.sym dst mach - dstgroup - dmode)) + ()) +) + +; m16c variants +(define-pmacro (binary-arith16-imm-dst-defn smode dmode wstr wbit op suffix opc1 opc2 opc3 sem) + (begin + (binary-arith-imm-dst-defn 16 (.sym Imm-32- smode) 16-16 dmode wstr op suffix + (+ opc1 opc2 (f-7-1 wbit) opc3 (.sym dst16-16-16- dmode) (.sym Imm-32- smode)) + sem) + (binary-arith-imm-dst-defn 16 (.sym Imm-24- smode) 16-8 dmode wstr op suffix + (+ opc1 opc2 (f-7-1 wbit) opc3 (.sym dst16-16-8- dmode) (.sym Imm-24- smode)) + sem) + (binary-arith-imm-dst-defn 16 (.sym Imm-16- smode) basic dmode wstr op suffix + (+ opc1 opc2 (f-7-1 wbit) opc3 (.sym dst16-basic- dmode) (.sym Imm-16- smode)) + sem) + ) +) + +; m32c Unprefixed variants +(define-pmacro (binary-arith32-imm-dst-Unprefixed smode dmode wstr wbit op suffix opc1 opc2 opc3 sem) + (begin + (binary-arith-imm-dst-defn 32 (.sym Imm-40- smode) 16-24-Unprefixed dmode wstr op suffix + (+ (f-0-4 opc1) (f-10-2 opc2) (f-7-1 wbit) (f-12-4 opc3) (.sym dst32-16-24-Unprefixed- dmode) (.sym Imm-40- smode)) + sem) + (binary-arith-imm-dst-defn 32 (.sym Imm-32- smode) 16-16-Unprefixed dmode wstr op suffix + (+ (f-0-4 opc1) (f-10-2 opc2) (f-7-1 wbit) (f-12-4 opc3) (.sym dst32-16-16-Unprefixed- dmode) (.sym Imm-32- smode)) + sem) + (binary-arith-imm-dst-defn 32 (.sym Imm-24- smode) 16-8-Unprefixed dmode wstr op suffix + (+ (f-0-4 opc1) (f-10-2 opc2) (f-7-1 wbit) (f-12-4 opc3) (.sym dst32-16-8-Unprefixed- dmode) (.sym Imm-24- smode)) + sem) + (binary-arith-imm-dst-defn 32 (.sym Imm-16- smode) basic-Unprefixed dmode wstr op suffix + (+ (f-0-4 opc1) (f-10-2 opc2) (f-7-1 wbit) (f-12-4 opc3) (.sym dst32-basic-Unprefixed- dmode) (.sym Imm-16- smode)) + sem) + ) +) + +; m32c Prefixed variants +(define-pmacro (binary-arith32-imm-dst-Prefixed smode dmode wstr wbit op suffix opc1 opc2 opc3 sem) + (begin + (binary-arith-imm-dst-defn 32 (.sym Imm-48- smode) 24-24-Prefixed dmode wstr op suffix + (+ (f-0-4 0) (f-4-4 1) (f-8-4 opc1) (f-18-2 opc2) (f-15-1 wbit) (f-20-4 opc3) (.sym dst32-24-24-Prefixed- dmode) (.sym Imm-48- smode)) + sem) + (binary-arith-imm-dst-defn 32 (.sym Imm-40- smode) 24-16-Prefixed dmode wstr op suffix + (+ (f-0-4 0) (f-4-4 1) (f-8-4 opc1) (f-18-2 opc2) (f-15-1 wbit) (f-20-4 opc3) (.sym dst32-24-16-Prefixed- dmode) (.sym Imm-40- smode)) + sem) + (binary-arith-imm-dst-defn 32 (.sym Imm-32- smode) 24-8-Prefixed dmode wstr op suffix + (+ (f-0-4 0) (f-4-4 1) (f-8-4 opc1) (f-18-2 opc2) (f-15-1 wbit) (f-20-4 opc3) (.sym dst32-24-8-Prefixed- dmode) (.sym Imm-32- smode)) + sem) + (binary-arith-imm-dst-defn 32 (.sym Imm-24- smode) basic-Prefixed dmode wstr op suffix + (+ (f-0-4 0) (f-4-4 1) (f-8-4 opc1) (f-18-2 opc2) (f-15-1 wbit) (f-20-4 opc3) (.sym dst32-basic-Prefixed- dmode) (.sym Imm-24- smode)) + sem) + ) +) + +; All m32c variants +(define-pmacro (binary-arith32-imm-dst-defn smode dmode wstr wbit op suffix opc1 opc2 opc3 sem) + (begin + ; Multi insns are tried for assembly in the reverse order in which they appear here, so + ; define the absolute-indirect insns first in order to prevent them from being selected + ; when the mode is register-indirect +; (binary-arith-imm-dst-defn 32 (.sym Imm-48- smode) 24-24-absolute-indirect dmode wstr op suffix +; (+ (f-0-4 0) (f-4-4 9) (f-8-4 opc1) (f-18-2 opc2) (f-15-1 wbit) (f-20-4 opc3) (.sym dst32-24-24-absolute-indirect- dmode) (.sym Imm-48- smode)) +; sem) +; (binary-arith-imm-dst-defn 32 (.sym Imm-40- smode) 24-16-absolute-indirect dmode wstr op suffix +; (+ (f-0-4 0) (f-4-4 9) (f-8-4 opc1) (f-18-2 opc2) (f-15-1 wbit) (f-20-4 opc3) (.sym dst32-24-16-absolute-indirect- dmode) (.sym Imm-40- smode)) +; sem) + ; Unprefixed modes next + (binary-arith32-imm-dst-Unprefixed smode dmode wstr wbit op suffix opc1 opc2 opc3 sem) + + ; Remaining indirect modes +; (binary-arith-imm-dst-defn 32 (.sym Imm-24- smode) basic-indirect dmode wstr op suffix +; (+ (f-0-4 0) (f-4-4 9) (f-8-4 opc1) (f-18-2 opc2) (f-15-1 wbit) (f-20-4 opc3) (.sym dst32-basic-indirect- dmode) (.sym Imm-24- smode)) +; sem) +; (binary-arith-imm-dst-defn 32 (.sym Imm-48- smode) 24-24-indirect dmode wstr op suffix +; (+ (f-0-4 0) (f-4-4 9) (f-8-4 opc1) (f-18-2 opc2) (f-15-1 wbit) (f-20-4 opc3) (.sym dst32-24-24-indirect- dmode) (.sym Imm-48- smode)) +; sem) +; (binary-arith-imm-dst-defn 32 (.sym Imm-40- smode) 24-16-indirect dmode wstr op suffix +; (+ (f-0-4 0) (f-4-4 9) (f-8-4 opc1) (f-18-2 opc2) (f-15-1 wbit) (f-20-4 opc3) (.sym dst32-24-16-indirect- dmode) (.sym Imm-40- smode)) +; sem) +; (binary-arith-imm-dst-defn 32 (.sym Imm-32- smode) 24-8-indirect dmode wstr op suffix +; (+ (f-0-4 0) (f-4-4 9) (f-8-4 opc1) (f-18-2 opc2) (f-15-1 wbit) (f-20-4 opc3) (.sym dst32-24-8-indirect- dmode) (.sym Imm-32- smode)) +; sem) + ) +) + +(define-pmacro (binary-arith-imm-dst-mach mach op suffix opc1 opc2 opc3 sem) + (begin + (.apply (.sym binary-arith mach -imm-dst-defn) (QI QI .b 0 op suffix opc1 opc2 opc3 sem)) + (.apply (.sym binary-arith mach -imm-dst-defn) (HI HI .w 1 op suffix opc1 opc2 opc3 sem)) + ) +) + +(define-pmacro (binary-arith-imm-dst op suffix opc16-1 opc16-2 opc16-3 opc32-1 opc32-2 opc32-3 sem) + (begin + (binary-arith-imm-dst-mach 16 op suffix opc16-1 opc16-2 opc16-3 sem) + (binary-arith-imm-dst-mach 32 op suffix opc32-1 opc32-2 opc32-3 sem) + ) +) + +;------------------------------------------------------------- +;<arith>.size:Q #imm4,dst -- for m16c and m32c +;------------------------------------------------------------- + +(define-pmacro (binary-arith-imm4-dst-defn mach src dstgroup mode wstr op encoding sem) + (dni (.sym op mach wstr - imm4-Q - dstgroup) + (.str op wstr " " mach "-imm4-Q-" dstgroup "-" mode) + ((machine mach) RL_1ADDR) + (.str op wstr "$Q #${" src "},${dst" mach "-" dstgroup "-" mode "}") + encoding + (sem mode src (.sym dst mach - dstgroup - mode)) + ()) +) + +; m16c variants +(define-pmacro (binary-arith16-imm4-dst-defn mode wstr wbit1 wbit2 op opc1 opc2 sem) + (binary-arith-imm4-dst-defn 16 Imm-8-s4 16 mode wstr op + (+ opc1 opc2 (f-7-1 wbit2) Imm-8-s4 (.sym dst16-16- mode)) + sem) +) + +(define-pmacro (binary-arith16-shimm4-dst-defn mode wstr wbit1 wbit2 op opc1 opc2 sem) + (binary-arith-imm4-dst-defn 16 Imm-sh-8-s4 16 mode wstr op + (+ opc1 opc2 (f-7-1 wbit2) Imm-sh-8-s4 (.sym dst16-16- mode)) + sem) +) + +; m32c variants +(define-pmacro (binary-arith32-imm4-dst-defn mode wstr wbit1 wbit2 op opc1 opc2 sem) + (begin + ; Multi insns are tried for assembly in the reverse order in which they appear here, so + ; define the absolute-indirect insns first in order to prevent them from being selected + ; when the mode is register-indirect +; (binary-arith-imm4-dst-defn 32 Imm-20-s4 24-absolute-indirect mode wstr op +; (+ (f-0-4 0) (f-4-4 9) (f-8-3 opc1) (f-11-1 wbit1) (f-15-1 wbit2) (.sym dst32-24-absolute-indirect- mode) (f-18-2 opc2) Imm-20-s4) +; sem) + (binary-arith-imm4-dst-defn 32 Imm-12-s4 16-Unprefixed mode wstr op + (+ (f-0-3 opc1) (f-3-1 wbit1) (f-7-1 wbit2) (.sym dst32-16-Unprefixed- mode) (f-10-2 opc2) Imm-12-s4) + sem) +; (binary-arith-imm4-dst-defn 32 Imm-20-s4 24-indirect mode wstr op +; (+ (f-0-4 0) (f-4-4 9) (f-8-3 opc1) (f-11-1 wbit1) (f-15-1 wbit2) (.sym dst32-24-indirect- mode) (f-18-2 opc2) Imm-20-s4) +; sem) + ) +) + +(define-pmacro (binary-arith32-shimm4-dst-defn mode wstr wbit1 wbit2 op opc1 opc2 sem) + (begin + ; Multi insns are tried for assembly in the reverse order in which they appear here, so + ; define the absolute-indirect insns first in order to prevent them from being selected + ; when the mode is register-indirect +; (binary-arith-imm4-dst-defn 32 Imm-sh-20-s4 24-absolute-indirect mode wstr op +; (+ (f-0-4 0) (f-4-4 9) (f-8-3 opc1) (f-11-1 wbit1) (f-15-1 wbit2) (.sym dst32-24-absolute-indirect- mode) (f-18-2 opc2) Imm-sh-20-s4) +; sem) + (binary-arith-imm4-dst-defn 32 Imm-sh-12-s4 16-Unprefixed mode wstr op + (+ (f-0-3 opc1) (f-3-1 wbit1) (f-7-1 wbit2) (.sym dst32-16-Unprefixed- mode) (f-10-2 opc2) Imm-sh-12-s4) + sem) +; (binary-arith-imm4-dst-defn 32 Imm-sh-20-s4 24-indirect mode wstr op +; (+ (f-0-4 0) (f-4-4 9) (f-8-3 opc1) (f-11-1 wbit1) (f-15-1 wbit2) (.sym dst32-24-indirect- mode) (f-18-2 opc2) Imm-sh-20-s4) +; sem) + ) +) + +(define-pmacro (binary-arith-imm4-dst-mach mach op opc1 opc2 sem) + (begin + (.apply (.sym binary-arith mach -imm4-dst-defn) (QI .b 0 0 op opc1 opc2 sem)) + (.apply (.sym binary-arith mach -imm4-dst-defn) (HI .w 0 1 op opc1 opc2 sem)) + ) +) + +(define-pmacro (binary-arith-imm4-dst op opc16-1 opc16-2 opc32-1 opc32-2 sem) + (begin + (binary-arith-imm4-dst-mach 16 op opc16-1 opc16-2 sem) + (binary-arith-imm4-dst-mach 32 op opc32-1 opc32-2 sem) + ) +) + +;------------------------------------------------------------- +;<arith>.size:G src,dst -- for m16c and m32c +;------------------------------------------------------------- + +(define-pmacro (binary-arith-src-dst-defn mach srcgroup dstgroup smode dmode wstr op suffix encoding sem) + (dni (.sym op mach wstr - srcgroup - dstgroup) + (.str op wstr " dst" mach "-" srcgroup "-" dstgroup "-" dmode) + ((machine mach) RL_2ADDR) + (.str op wstr "$" suffix " ${src" mach "-" srcgroup "-" smode "},${dst" mach "-" dstgroup "-" dmode "}") + encoding + (sem dmode (.sym src mach - srcgroup - smode) (.sym dst mach - dstgroup - dmode)) + ()) +) + +; m16c variants +(define-pmacro (binary-arith16-src-dst-defn smode dmode wstr wbit op suffix opc1 opc2 sem) + (begin + (binary-arith-src-dst-defn 16 basic 16 smode dmode wstr op suffix + (+ opc1 opc2 (f-7-1 wbit) (.sym src16-basic- smode) (.sym dst16-16- dmode)) + sem) + (binary-arith-src-dst-defn 16 16-16 32 smode dmode wstr op suffix + (+ opc1 opc2 (f-7-1 wbit) (.sym src16-16-16- smode) (.sym dst16-32- dmode)) + sem) + (binary-arith-src-dst-defn 16 16-8 24 smode dmode wstr op suffix + (+ opc1 opc2 (f-7-1 wbit) (.sym src16-16-8- smode) (.sym dst16-24- dmode)) + sem) + ) +) + +; m32c Prefixed variants +(define-pmacro (binary-arith32-src-dst-Prefixed smode dmode wstr wbit op suffix opc1 opc2 sem) + (begin + (binary-arith-src-dst-defn 32 basic-Prefixed 24-Prefixed smode dmode wstr op suffix + (+ (f-0-4 0) (f-4-4 1) (f-8-1 opc1) (f-15-1 wbit) (.sym src32-basic-Prefixed- smode) (.sym dst32-24-Prefixed- dmode) (f-20-4 opc2)) + sem) + (binary-arith-src-dst-defn 32 24-24-Prefixed 48-Prefixed smode dmode wstr op suffix + (+ (f-0-4 0) (f-4-4 1) (f-8-1 opc1) (f-15-1 wbit) (.sym src32-24-24-Prefixed- smode) (.sym dst32-48-Prefixed- dmode) (f-20-4 opc2)) + sem) + (binary-arith-src-dst-defn 32 24-16-Prefixed 40-Prefixed smode dmode wstr op suffix + (+ (f-0-4 0) (f-4-4 1) (f-8-1 opc1) (f-15-1 wbit) (.sym src32-24-16-Prefixed- smode) (.sym dst32-40-Prefixed- dmode) (f-20-4 opc2)) + sem) + (binary-arith-src-dst-defn 32 24-8-Prefixed 32-Prefixed smode dmode wstr op suffix + (+ (f-0-4 0) (f-4-4 1) (f-8-1 opc1) (f-15-1 wbit) (.sym src32-24-8-Prefixed- smode) (.sym dst32-32-Prefixed- dmode) (f-20-4 opc2)) + sem) + ) +) + +; all m32c variants +(define-pmacro (binary-arith32-src-dst-defn smode dmode wstr wbit op suffix opc1 opc2 sem) + (begin + ; Multi insns are tried for assembly in the reverse order in which they appear here, so + ; define the absolute-indirect insns first in order to prevent them from being selected + ; when the mode is register-indirect +; (binary-arith-src-dst-defn 32 24-24-absolute-indirect 48-absolute-indirect smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-24-absolute-indirect- smode) (.sym dst32-48-absolute-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-16-absolute-indirect 40-absolute-indirect smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-16-absolute-indirect- smode) (.sym dst32-40-absolute-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-24-absolute-indirect 48-Prefixed smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 1) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-24-absolute-indirect- smode) (.sym dst32-48-Prefixed- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-16-absolute-indirect 40-Prefixed smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 1) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-16-absolute-indirect- smode) (.sym dst32-40-Prefixed- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-24-absolute-indirect 48-indirect smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-24-absolute-indirect- smode) (.sym dst32-48-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-16-absolute-indirect 40-indirect smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-16-absolute-indirect- smode) (.sym dst32-40-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 basic-Prefixed 24-absolute-indirect smode dmode wstr op suffix +; (+ (f-0-4 0) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-basic-Prefixed- smode) (.sym dst32-24-absolute-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-24-Prefixed 48-absolute-indirect smode dmode wstr op suffix +; (+ (f-0-4 0) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-24-Prefixed- smode) (.sym dst32-48-absolute-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-16-Prefixed 40-absolute-indirect smode dmode wstr op suffix +; (+ (f-0-4 0) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-16-Prefixed- smode) (.sym dst32-40-absolute-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-8-Prefixed 32-absolute-indirect smode dmode wstr op suffix +; (+ (f-0-4 0) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-8-Prefixed- smode) (.sym dst32-32-absolute-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 basic-indirect 24-absolute-indirect smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-basic-indirect- smode) (.sym dst32-24-absolute-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-24-indirect 48-absolute-indirect smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-24-indirect- smode) (.sym dst32-48-absolute-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-16-indirect 40-absolute-indirect smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-16-indirect- smode) (.sym dst32-40-absolute-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-8-indirect 32-absolute-indirect smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-8-indirect- smode) (.sym dst32-32-absolute-indirect- dmode) (f-20-4 opc2)) +; sem) + (binary-arith-src-dst-defn 32 basic-Unprefixed 16-Unprefixed smode dmode wstr op suffix + (+ (f-0-1 opc1) (f-7-1 wbit) (.sym src32-basic-Unprefixed- smode) (.sym dst32-16-Unprefixed- dmode) (f-12-4 opc2)) + sem) + (binary-arith-src-dst-defn 32 16-24-Unprefixed 40-Unprefixed smode dmode wstr op suffix + (+ (f-0-1 opc1) (f-7-1 wbit) (.sym src32-16-24-Unprefixed- smode) (.sym dst32-40-Unprefixed- dmode) (f-12-4 opc2)) + sem) + (binary-arith-src-dst-defn 32 16-16-Unprefixed 32-Unprefixed smode dmode wstr op suffix + (+ (f-0-1 opc1) (f-7-1 wbit) (.sym src32-16-16-Unprefixed- smode) (.sym dst32-32-Unprefixed- dmode) (f-12-4 opc2)) + sem) + (binary-arith-src-dst-defn 32 16-8-Unprefixed 24-Unprefixed smode dmode wstr op suffix + (+ (f-0-1 opc1) (f-7-1 wbit) (.sym src32-16-8-Unprefixed- smode) (.sym dst32-24-Unprefixed- dmode) (f-12-4 opc2)) + sem) +; (binary-arith-src-dst-defn 32 basic-indirect 24-Prefixed smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 1) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-basic-indirect- smode) (.sym dst32-24-Prefixed- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-24-indirect 48-Prefixed smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 1) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-24-indirect- smode) (.sym dst32-48-Prefixed- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-16-indirect 40-Prefixed smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 1) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-16-indirect- smode) (.sym dst32-40-Prefixed- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-8-indirect 32-Prefixed smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 1) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-8-indirect- smode) (.sym dst32-32-Prefixed- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 basic-Prefixed 24-indirect smode dmode wstr op suffix +; (+ (f-0-4 0) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-basic-Prefixed- smode) (.sym dst32-24-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-24-Prefixed 48-indirect smode dmode wstr op suffix +; (+ (f-0-4 0) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-24-Prefixed- smode) (.sym dst32-48-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-16-Prefixed 40-indirect smode dmode wstr op suffix +; (+ (f-0-4 0) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-16-Prefixed- smode) (.sym dst32-40-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-8-Prefixed 32-indirect smode dmode wstr op suffix +; (+ (f-0-4 0) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-8-Prefixed- smode) (.sym dst32-32-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 basic-indirect 24-indirect smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-basic-indirect- smode) (.sym dst32-24-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-24-indirect 48-indirect smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-24-indirect- smode) (.sym dst32-48-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-16-indirect 40-indirect smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-16-indirect- smode) (.sym dst32-40-indirect- dmode) (f-20-4 opc2)) +; sem) +; (binary-arith-src-dst-defn 32 24-8-indirect 32-indirect smode dmode wstr op suffix +; (+ (f-0-4 4) (f-4-4 9) (f-8-1 opc1) (f-15-1 wbit) +; (.sym src32-24-8-indirect- smode) (.sym dst32-32-indirect- dmode) (f-20-4 opc2)) +; sem) + ) +) + +(define-pmacro (binary-arith-src-dst-mach mach op suffix opc1 opc2 sem) + (begin + (.apply (.sym binary-arith mach -src-dst-defn) (QI QI .b 0 op suffix opc1 opc2 sem)) + (.apply (.sym binary-arith mach -src-dst-defn) (HI HI .w 1 op suffix opc1 opc2 sem)) + ) +) + +(define-pmacro (binary-arith-src-dst op suffix opc16-1 opc16-2 opc32-1 opc32-2 sem) + (begin + (binary-arith-src-dst-mach 16 op suffix opc16-1 opc16-2 sem) + (binary-arith-src-dst-mach 32 op suffix opc32-1 opc32-2 sem) + ) +) + +;------------------------------------------------------------- +;<arith>.size:S #imm,dst -- for m32c +;------------------------------------------------------------- + +(define-pmacro (binary-arith32-s-imm-dst-defn src dstgroup mode wstr op encoding sem) + (dni (.sym op 32 wstr - imm-S - dstgroup) + (.str op wstr " 32-imm-S-" dstgroup "-" mode) + ((machine 32)) + (.str op wstr "$S #${" src "},${dst32-" dstgroup "-" mode "}") + encoding + (sem mode src (.sym dst32- dstgroup - mode)) + ()) +) + +(define-pmacro (binary-arith32-z-imm-dst-defn src dstgroup mode wstr op encoding sem) + (dni (.sym op 32 wstr - imm-Z - dstgroup) + (.str op wstr " 32-imm-Z-" dstgroup "-" mode) + ((machine 32)) + (.str op wstr "$Z #0,${dst32-" dstgroup "-" mode "}") + encoding + (sem mode (const 0) (.sym dst32- dstgroup - mode)) + ()) +) + +(define-pmacro (binary-arith32-s-imm-dst mode wstr wbit op opc1 opc2 sem) + (begin +; (binary-arith32-s-imm-dst-defn (.sym Imm-32- mode) 2-S-absolute-indirect mode wstr op +; (+ (f-0-4 0) (f-4-4 9) (f-8-2 opc1) (.sym dst32-2-S-absolute-indirect- mode) (f-12-3 opc2) (f-15-1 wbit) (.sym Imm-32- mode)) +; sem) + (binary-arith32-s-imm-dst-defn (.sym Imm-8- mode) 2-S-basic mode wstr op + (+ (f-0-2 opc1) (.sym dst32-2-S-basic- mode) (f-4-3 opc2) (f-7-1 wbit) (.sym Imm-8- mode)) + sem) + (binary-arith32-s-imm-dst-defn (.sym Imm-24- mode) 2-S-16 mode wstr op + (+ (f-0-2 opc1) (.sym dst32-2-S-16- mode) (f-4-3 opc2) (f-7-1 wbit) (.sym Imm-24- mode)) + sem) + (binary-arith32-s-imm-dst-defn (.sym Imm-16- mode) 2-S-8 mode wstr op + (+ (f-0-2 opc1) (.sym dst32-2-S-8- mode) (f-4-3 opc2) (f-7-1 wbit) (.sym Imm-16- mode)) + sem) +; (binary-arith32-s-imm-dst-defn (.sym Imm-24- mode) 2-S-8-indirect mode wstr op +; (+ (f-0-4 0) (f-4-4 9) (f-8-2 opc1) (.sym dst32-2-S-8-indirect- mode) (f-12-3 opc2) (f-15-1 wbit) (.sym Imm-24- mode)) +; sem) + ) +) + +(define-pmacro (binary-arith32-z-imm-dst mode wstr wbit op opc1 opc2 sem) + (begin +; (binary-arith32-z-imm-dst-defn (.sym Imm-32- mode) 2-S-absolute-indirect mode wstr op +; (+ (f-0-4 0) (f-4-4 9) (f-8-2 opc1) (.sym dst32-2-S-absolute-indirect- mode) (f-12-3 opc2) (f-15-1 wbit) (.sym Imm-32- mode)) +; sem) + (binary-arith32-z-imm-dst-defn (.sym Imm-8- mode) 2-S-basic mode wstr op + (+ (f-0-2 opc1) (.sym dst32-2-S-basic- mode) (f-4-3 opc2) (f-7-1 wbit)) + sem) + (binary-arith32-z-imm-dst-defn (.sym Imm-24- mode) 2-S-16 mode wstr op + (+ (f-0-2 opc1) (.sym dst32-2-S-16- mode) (f-4-3 opc2) (f-7-1 wbit)) + sem) + (binary-arith32-z-imm-dst-defn (.sym Imm-16- mode) 2-S-8 mode wstr op + (+ (f-0-2 opc1) (.sym dst32-2-S-8- mode) (f-4-3 opc2) (f-7-1 wbit)) + sem) +; (binary-arith32-z-imm-dst-defn (.sym Imm-24- mode) 2-S-8-indirect mode wstr op +; (+ (f-0-4 0) (f-4-4 9) (f-8-2 opc1) (.sym dst32-2-S-8-indirect- mode) (f-12-3 opc2) (f-15-1 wbit) (.sym Imm-24- mode)) +; sem) + ) +) + +;------------------------------------------------------------- +;<arith>.L:S #imm1,An -- for m32c +;------------------------------------------------------------- + +(define-pmacro (binary-arith32-l-s-imm1-an op opc1 opc2 sem) + (begin + (dni (.sym op 32.l-s-imm1-S-an) + (.str op ".l 32-imm1-S-an") + ((machine 32)) + (.str op ".l$S #${Imm1-S},${dst32-an-S}") + (+ opc1 Imm1-S opc2 dst32-an-S) + (sem SI Imm1-S dst32-an-S) + ()) + ) +) + +;------------------------------------------------------------- +;<arith>.L:Q #imm3,sp -- for m32c +;------------------------------------------------------------- + +(define-pmacro (binary-arith32-l-q-imm3-sp op opc1 opc2 sem) + (begin + (dni (.sym op 32.l-imm3-Q) + (.str op ".l 32-imm3-Q") + ((machine 32)) + (.str op ".l$Q #${Imm3-S},sp") + (+ opc1 Imm3-S opc2) + (sem SI Imm3-S sp) + ()) + ) +) + +;------------------------------------------------------------- +;<arith>.L:S #imm8,sp -- for m32c +;------------------------------------------------------------- + +(define-pmacro (binary-arith32-l-s-imm8-sp op opc1 opc2 opc3 opc4 sem) + (begin + (dni (.sym op 32.l-imm8-S) + (.str op ".l 32-imm8-S") + ((machine 32)) + (.str op ".l$S #${Imm-16-QI},sp") + (+ opc1 opc2 opc3 opc4 Imm-16-QI) + (sem SI Imm-16-QI sp) + ()) + ) +) + +;------------------------------------------------------------- +;<arith>.L:G #imm16,sp -- for m32c +;------------------------------------------------------------- + +(define-pmacro (binary-arith32-l-g-imm16-sp op opc1 opc2 opc3 opc4 sem) + (begin + (dni (.sym op 32.l-imm16-G) + (.str op ".l 32-imm16-G") + ((machine 32)) + (.str op ".l$G #${Imm-16-HI},sp") + (+ opc1 opc2 opc3 opc4 Imm-16-HI) + (sem SI Imm-16-HI sp) + ()) + ) +) + +;------------------------------------------------------------- +;<arith>jnz.size #imm4,dst,label -- for m16c and m32c +;------------------------------------------------------------- + +(define-pmacro (arith-jnz-imm4-dst-defn mach src dstgroup label mode wstr op encoding sem) + (dni (.sym op mach wstr - imm4 - dstgroup) + (.str op wstr " " mach "-imm4-" dstgroup "-" label "-" mode) + (RL_JUMP RELAXABLE (machine mach)) + (.str op wstr " #${" src "},${dst" mach "-" dstgroup "-" mode "},${" label "}") + encoding + (sem mode src (.sym dst mach - dstgroup - mode) label) + ()) +) + +; m16c variants +(define-pmacro (arith-jnz16-imm4-dst-defn mode wstr wbit op i4n opc1 opc2 sem) + (begin + (arith-jnz-imm4-dst-defn 16 (.sym Imm-8- i4n) basic Lab-16-8 mode wstr op + (+ opc1 opc2 (f-7-1 wbit) (.sym Imm-8- i4n) (.sym dst16-basic- mode) Lab-16-8) + sem) + (arith-jnz-imm4-dst-defn 16 (.sym Imm-8- i4n) 16-16 Lab-32-8 mode wstr op + (+ opc1 opc2 (f-7-1 wbit) (.sym Imm-8- i4n) (.sym dst16-16-16- mode) Lab-32-8) + sem) + (arith-jnz-imm4-dst-defn 16 (.sym Imm-8- i4n) 16-8 Lab-24-8 mode wstr op + (+ opc1 opc2 (f-7-1 wbit) (.sym Imm-8- i4n) (.sym dst16-16-8- mode) Lab-24-8) + sem) + ) +) + +; m32c variants +(define-pmacro (arith-jnz32-imm4-dst-defn mode wstr wbit op i4n opc1 opc2 sem) + (begin + (arith-jnz-imm4-dst-defn 32 (.sym Imm-12- i4n) basic-Unprefixed Lab-16-8 mode wstr op + (+ (f-0-4 opc1) (f-7-1 wbit) (.sym dst32-basic-Unprefixed- mode) (f-10-2 opc2) (.sym Imm-12- i4n) Lab-16-8) + sem) + (arith-jnz-imm4-dst-defn 32 (.sym Imm-12- i4n) 16-24-Unprefixed Lab-40-8 mode wstr op + (+ (f-0-4 opc1) (f-7-1 wbit) (.sym dst32-16-24-Unprefixed- mode) (f-10-2 opc2) (.sym Imm-12- i4n) Lab-40-8) + sem) + (arith-jnz-imm4-dst-defn 32 (.sym Imm-12- i4n) 16-16-Unprefixed Lab-32-8 mode wstr op + (+ (f-0-4 opc1) (f-7-1 wbit) (.sym dst32-16-16-Unprefixed- mode) (f-10-2 opc2) (.sym Imm-12- i4n) Lab-32-8) + sem) + (arith-jnz-imm4-dst-defn 32 (.sym Imm-12- i4n) 16-8-Unprefixed Lab-24-8 mode wstr op + (+ (f-0-4 opc1) (f-7-1 wbit) (.sym dst32-16-8-Unprefixed- mode) (f-10-2 opc2) (.sym Imm-12- i4n) Lab-24-8) + sem) + ) +) + +(define-pmacro (arith-jnz-imm4-dst-mach mach op i4n opc1 opc2 sem) + (begin + (.apply (.sym arith-jnz mach -imm4-dst-defn) (QI .b 0 op i4n opc1 opc2 sem)) + (.apply (.sym arith-jnz mach -imm4-dst-defn) (HI .w 1 op i4n opc1 opc2 sem)) + ) +) + +(define-pmacro (arith-jnz-imm4-dst op i4n opc16-1 opc16-2 opc32-1 opc32-2 sem) + (begin + (arith-jnz-imm4-dst-mach 16 op i4n opc16-1 opc16-2 sem) + (arith-jnz-imm4-dst-mach 32 op i4n opc32-1 opc32-2 sem) + ) +) + +;------------------------------------------------------------- +;mov.size dsp8[sp],dst -- for m16c and m32c +;------------------------------------------------------------- +(define-pmacro (mov-dspsp-dst-defn mach dstgroup dsp mode wstr op encoding sem) + (dni (.sym op mach wstr -dspsp-dst- dstgroup) + (.str op wstr " " mach "-dsp[sp]-" dstgroup "-" dsp "-" mode) + ((machine mach)) + (.str op wstr "$G ${" dsp "}[sp],${dst" mach "-" dstgroup "-" mode "}") + encoding + (sem mach mode dsp (.sym dst mach - dstgroup - mode)) + ()) +) +(define-pmacro (mov-src-dspsp-defn mach dstgroup dsp mode wstr op encoding sem) + (dni (.sym op mach wstr -dst-dspsp- dstgroup) + (.str op wstr " " mach "-dsp[sp]-" dstgroup "-" dsp "-" mode) + ((machine mach)) + (.str op wstr "$G ${dst" mach "-" dstgroup "-" mode "},${" dsp "}[sp]") + encoding + (sem mach mode (.sym dst mach - dstgroup - mode) dsp) + ()) +) + +; m16c variants +(define-pmacro (mov16-dspsp-dst-defn mode wstr wbit op opc1 opc2 opc3 sem) + (begin + (mov-dspsp-dst-defn 16 basic Dsp-16-s8 mode wstr op + (+ opc1 opc2 (f-7-1 wbit) opc3 (.sym dst16-basic- mode) Dsp-16-s8) + sem) + (mov-dspsp-dst-defn 16 16-16 Dsp-32-s8 mode wstr op + (+ opc1 opc2 (f-7-1 wbit) opc3 (.sym dst16-16-16- mode) Dsp-32-s8) + sem) + (mov-dspsp-dst-defn 16 16-8 Dsp-24-s8 mode wstr op + (+ opc1 opc2 (f-7-1 wbit) opc3 (.sym dst16-16-8- mode) Dsp-24-s8) + sem) + ) +) + +(define-pmacro (mov16-src-dspsp-defn mode wstr wbit op opc1 opc2 opc3 sem) + (begin + (mov-src-dspsp-defn 16 basic Dsp-16-s8 mode wstr op + (+ opc1 opc2 (f-7-1 wbit) opc3 (.sym dst16-basic- mode) Dsp-16-s8) + sem) + (mov-src-dspsp-defn 16 16-16 Dsp-32-s8 mode wstr op + (+ opc1 opc2 (f-7-1 wbit) opc3 (.sym dst16-16-16- mode) Dsp-32-s8) + sem) + (mov-src-dspsp-defn 16 16-8 Dsp-24-s8 mode wstr op + (+ opc1 opc2 (f-7-1 wbit) opc3 (.sym dst16-16-8- mode) Dsp-24-s8) + sem) + ) +) + +; m32c variants +(define-pmacro (mov32-dspsp-dst-defn mode wstr wbit op opc1 opc2 opc3 sem) + (begin + (mov-dspsp-dst-defn 32 basic-Unprefixed Dsp-16-s8 mode wstr op + (+ (f-0-4 opc1) (f-7-1 wbit) (.sym dst32-basic-Unprefixed- mode) (f-10-2 opc2) (f-12-4 opc3) Dsp-16-s8) + sem) + (mov-dspsp-dst-defn 32 16-24-Unprefixed Dsp-40-s8 mode wstr op + (+ (f-0-4 opc1) (f-7-1 wbit) (.sym dst32-16-24-Unprefixed- mode) (f-10-2 opc2) (f-12-4 opc3) Dsp-40-s8) + sem) + (mov-dspsp-dst-defn 32 16-16-Unprefixed Dsp-32-s8 mode wstr op + (+ (f-0-4 opc1) (f-7-1 wbit) (.sym dst32-16-16-Unprefixed- mode) (f-10-2 opc2) (f-12-4 opc3) Dsp-32-s8) + sem) + (mov-dspsp-dst-defn 32 16-8-Unprefixed Dsp-24-s8 mode wstr op + (+ (f-0-4 opc1) (f-7-1 wbit) (.sym dst32-16-8-Unprefixed- mode) (f-10-2 opc2) (f-12-4 opc3) Dsp-24-s8) + sem) + ) +) +(define-pmacro (mov32-src-dspsp-defn mode wstr wbit op opc1 opc2 opc3 sem) + (begin + (mov-src-dspsp-defn 32 basic-Unprefixed Dsp-16-s8 mode wstr op + (+ (f-0-4 opc1) (f-7-1 wbit) (.sym dst32-basic-Unprefixed- mode) (f-10-2 opc2) (f-12-4 opc3) Dsp-16-s8) + sem) + (mov-src-dspsp-defn 32 16-24-Unprefixed Dsp-40-s8 mode wstr op + (+ (f-0-4 opc1) (f-7-1 wbit) (.sym dst32-16-24-Unprefixed- mode) (f-10-2 opc2) (f-12-4 opc3) Dsp-40-s8) + sem) + (mov-src-dspsp-defn 32 16-16-Unprefixed Dsp-32-s8 mode wstr op + (+ (f-0-4 opc1) (f-7-1 wbit) (.sym dst32-16-16-Unprefixed- mode) (f-10-2 opc2) (f-12-4 opc3) Dsp-32-s8) + sem) + (mov-src-dspsp-defn 32 16-8-Unprefixed Dsp-24-s8 mode wstr op + (+ (f-0-4 opc1) (f-7-1 wbit) (.sym dst32-16-8-Unprefixed- mode) (f-10-2 opc2) (f-12-4 opc3) Dsp-24-s8) + sem) + ) +) + +(define-pmacro (mov-src-dspsp-mach mach op opc1 opc2 opc3 sem) + (begin + (.apply (.sym mov mach -src-dspsp-defn) (QI .b 0 op opc1 opc2 opc3 sem)) + (.apply (.sym mov mach -src-dspsp-defn) (HI .w 1 op opc1 opc2 opc3 sem)) + ) +) + +(define-pmacro (mov-dspsp-dst-mach mach op opc1 opc2 opc3 sem) + (begin + (.apply (.sym mov mach -dspsp-dst-defn) (QI .b 0 op opc1 opc2 opc3 sem)) + (.apply (.sym mov mach -dspsp-dst-defn) (HI .w 1 op opc1 opc2 opc3 sem)) + ) +) + +(define-pmacro (mov-dspsp-dst op opc16-1 opc16-2 opc16-3 opc32-1 opc32-2 opc32-3 sem) + (begin + (mov-dspsp-dst-mach 16 op opc16-1 opc16-2 opc16-3 sem) + (mov-dspsp-dst-mach 32 op opc32-1 opc32-2 opc32-3 sem) + ) +) +(define-pmacro (mov-src-dspsp op opc16-1 opc16-2 opc16-3 opc32-1 opc32-2 opc32-3 sem) + (begin + (mov-src-dspsp-mach 16 op opc16-1 opc16-2 opc16-3 sem) + (mov-src-dspsp-mach 32 op opc32-1 opc32-2 opc32-3 sem) + ) +) + +;------------------------------------------------------------- +; lde dsp24,dst -- for m16c +;------------------------------------------------------------- + +(define-pmacro (lde-dst-dsp mode wstr wbit dstgroup srcdisp) + (begin + + (dni (.sym lde wstr - dstgroup -u20) + (.str "lde" wstr "-" dstgroup "-u20") + ((machine 16)) + (.str "lde" wstr " ${" srcdisp "},${dst16-" dstgroup "-" mode "}") + (+ (f-0-4 #x7) (f-4-3 #x2) (f-7-1 wbit) (f-8-4 #x8) + (.sym dst16- dstgroup - mode) srcdisp) + (nop) + ()) + + (dni (.sym lde wstr - dstgroup -u20a0) + (.str "lde" wstr "-" dstgroup "-u20a0") + ((machine 16)) + (.str "lde" wstr " ${" srcdisp "}[a0],${dst16-" dstgroup "-" mode "}") + (+ (f-0-4 #x7) (f-4-3 #x2) (f-7-1 wbit) (f-8-4 #x9) + (.sym dst16- dstgroup - mode) srcdisp) + (nop) + ()) + + (dni (.sym lde wstr - dstgroup -a1a0) + (.str "lde" wstr "-" dstgroup "-a1a0") + ((machine 16)) + (.str "lde" wstr " [a1a0],${dst16-" dstgroup "-" mode "}") + (+ (f-0-4 #x7) (f-4-3 #x2) (f-7-1 wbit) (f-8-4 #xa) + (.sym dst16- dstgroup - mode)) + (nop) + ()) + ) + ) + +(define-pmacro (lde-dst mode wstr wbit) + (begin + ; like: QI .b 0 + (lde-dst-dsp mode wstr wbit basic Dsp-16-u20) + (lde-dst-dsp mode wstr wbit 16-8 Dsp-24-u20) + (lde-dst-dsp mode wstr wbit 16-16 Dsp-32-u20) + ) +) + +;------------------------------------------------------------- +; ste dst,dsp24 -- for m16c +;------------------------------------------------------------- + +(define-pmacro (ste-dst-dsp mode wstr wbit dstgroup srcdisp) + (begin + + (dni (.sym ste wstr - dstgroup -u20) + (.str "ste" wstr "-" dstgroup "-u20") + ((machine 16)) + (.str "ste" wstr " ${dst16-" dstgroup "-" mode "},${" srcdisp "}") + (+ (f-0-4 #x7) (f-4-3 #x2) (f-7-1 wbit) (f-8-4 #x0) + (.sym dst16- dstgroup - mode) srcdisp) + (nop) + ()) + + (dni (.sym ste wstr - dstgroup -u20a0) + (.str "ste" wstr "-" dstgroup "-u20a0") + ((machine 16)) + (.str "ste" wstr " ${dst16-" dstgroup "-" mode "},${" srcdisp "}[a0]") + (+ (f-0-4 #x7) (f-4-3 #x2) (f-7-1 wbit) (f-8-4 #x1) + (.sym dst16- dstgroup - mode) srcdisp) + (nop) + ()) + + (dni (.sym ste wstr - dstgroup -a1a0) + (.str "ste" wstr "-" dstgroup "-a1a0") + ((machine 16)) + (.str "ste" wstr " ${dst16-" dstgroup "-" mode "},[a1a0]") + (+ (f-0-4 #x7) (f-4-3 #x2) (f-7-1 wbit) (f-8-4 #x2) + (.sym dst16- dstgroup - mode)) + (nop) + ()) + ) + ) + +(define-pmacro (ste-dst mode wstr wbit) + (begin + ; like: QI .b 0 + (ste-dst-dsp mode wstr wbit basic Dsp-16-u20) + (ste-dst-dsp mode wstr wbit 16-8 Dsp-24-u20) + (ste-dst-dsp mode wstr wbit 16-16 Dsp-32-u20) + ) +) + +;============================================================= +; Division +;------------------------------------------------------------- + +(define-pmacro (div-sem divop modop opmode reg src quot rem max min) + (sequence () + (if (eq src 0) + (set obit (const BI 1)) + (sequence ((opmode quot-result) (opmode rem-result)) + (set quot-result (divop opmode (ext opmode reg) src)) + (set rem-result (modop opmode (ext opmode reg) src)) + (set obit (orif (gt opmode quot-result max) + (lt opmode quot-result min))) + (set quot quot-result) + (set rem rem-result)))) +) + +;<divop>.size #imm -- for m16c and m32c +(define-pmacro (div-imm-defn mach wstr op src encoding divop modop opmode reg quot rem max min sem) + (dni (.sym op mach wstr - src) + (.str op mach wstr "-" src) + ((machine mach)) + (.str op wstr " #${" src "}") + encoding + (sem divop modop opmode reg src quot rem max min) + ()) +) +(define-pmacro (div16-imm-defn smode wstr wbit op divop modop opmode reg quot rem max min opc1 opc2 opc3 opc4 sem) + (div-imm-defn 16 wstr op (.sym Imm-16 - smode) + (+ opc1 opc2 (f-7-1 wbit) opc3 opc4 (.sym Imm-16 - smode)) + divop modop opmode reg quot rem max min + sem) +) +(define-pmacro (div32-imm-defn smode wstr wbit op divop modop opmode reg quot rem max min opc1 opc2 opc3 opc4 sem) + (div-imm-defn 32 wstr op (.sym Imm-16 - smode) + (+ (f-0-4 opc1) (f-4-4 opc2) (f-8-3 opc3) (f-11-1 wbit) (f-12-4 opc4) (.sym Imm-16 - smode)) + divop modop opmode reg quot rem max min + sem) +) +(define-pmacro (div-imm-mach mach op divop modop opmode max-QI min-QI max-HI min-HI opc1 opc2 opc3 opc4 sem) + (begin + (.apply (.sym div mach -imm-defn) (QI .b 0 op divop modop opmode R0 R0l R0h max-QI min-QI opc1 opc2 opc3 opc4 sem)) + (.apply (.sym div mach -imm-defn) (HI .w 1 op divop modop opmode R2R0 R0 R2 max-HI min-HI opc1 opc2 opc3 opc4 sem)) + ) +) +(define-pmacro (div-imm op divop modop opmode max-QI min-QI max-HI min-HI opc16-1 opc16-2 opc16-3 opc16-4 opc32-1 opc32-2 opc32-3 opc32-4 sem) + (begin + (div-imm-mach 16 op divop modop opmode max-QI min-QI max-HI min-HI opc16-1 opc16-2 opc16-3 opc16-4 sem) + (div-imm-mach 32 op divop modop opmode max-QI min-QI max-HI min-HI opc32-1 opc32-2 opc32-3 opc32-4 sem) + ) +) + +;<divop>.size src -- for m16c and m32c +(define-pmacro (div-src-defn mach wstr op src encoding divop modop opmode reg quot rem max min sem) + (dni (.sym op mach wstr - src) + (.str op mach wstr "-" src) + ((machine mach)) + (.str op wstr " ${" src "}") + encoding + (sem divop modop opmode reg src quot rem max min) + ()) +) +(define-pmacro (div16-src-defn smode wstr wbit op divop modop opmode reg quot rem max min opc1 opc2 opc3 sem) + (div-src-defn 16 wstr op (.sym dst16-16 - smode) + (+ opc1 opc2 (f-7-1 wbit) opc3 (.sym dst16-16 - smode)) + divop modop opmode reg quot rem max min + sem) +) +(define-pmacro (div32-src-defn smode wstr wbit op divop modop opmode reg quot rem max min opc1 opc2 opc3 sem) + (begin + ; Multi insns are tried for assembly in the reverse order in which they appear here, so + ; define the absolute-indirect insns first in order to prevent them from being selected + ; when the mode is register-indirect +; (div-src-defn 32 wstr op (.sym dst32-24-absolute-indirect- smode) +; (+ (f-0-4 0) (f-4-4 9) (f-8-4 opc1) (f-15-1 wbit) (f-18-2 opc2) (f-20-4 opc3) (.sym dst32-24-absolute-indirect - smode)) +; divop modop opmode reg quot rem max min +; sem) + (div-src-defn 32 wstr op (.sym dst32-16-Unprefixed- smode) + (+ (f-0-4 opc1) (f-7-1 wbit) (f-10-2 opc2) (f-12-4 opc3) (.sym dst32-16-Unprefixed- smode)) + divop modop opmode reg quot rem max min + sem) +; (div-src-defn 32 wstr op (.sym dst32-24-indirect- smode) +; (+ (f-0-4 0) (f-4-4 9) (f-8-4 opc1) (f-15-1 wbit) (f-18-2 opc2) (f-20-4 opc3) (.sym dst32-24-indirect - smode)) +; divop modop opmode reg quot rem max min +; sem) + ) +) +(define-pmacro (div-src-mach mach op divop modop opmode max-QI min-QI max-HI min-HI opc1 opc2 opc3 sem) + (begin + (.apply (.sym div mach -src-defn) (QI .b 0 op divop modop opmode R0 R0l R0h max-QI min-QI opc1 opc2 opc3 sem)) + (.apply (.sym div mach -src-defn) (HI .w 1 op divop modop opmode R2R0 R0 R2 max-HI min-HI opc1 opc2 opc3 sem)) + ) +) +(define-pmacro (div-src op divop modop opmode max-QI min-QI max-HI min-HI opc16-1 opc16-2 opc16-3 opc32-1 opc32-2 opc32-3 sem) + (begin + (div-src-mach 16 op divop modop opmode max-QI min-QI max-HI min-HI opc16-1 opc16-2 opc16-3 sem) + (div-src-mach 32 op divop modop opmode max-QI min-QI max-HI min-HI opc32-1 opc32-2 opc32-3 sem) + ) +) + +;============================================================= +; Bit manipulation +; +(define-pmacro (bit-insn-defn mach op suffix opnd encoding sem) + (dni (.sym op mach - suffix - opnd) + (.str op mach ":" suffix " " opnd) + ((machine mach)) + (.str op "$" suffix " ${" opnd "}") + encoding + (sem opnd) + ()) +) + +(define-pmacro (bitsrc16-defn op opc1 opc2 opc3 sem) + (bit-insn-defn 16 op X bit16-16 + (+ opc1 opc2 opc3 bit16-16) + sem) +) + +(define-pmacro (bitsrc32-defn op opc1 opc2 opc3 sem) + (begin + (bit-insn-defn 32 op X bit32-24-Prefixed + (+ (f-0-4 0) (f-4-4 1) (f-8-4 opc1) bit32-24-Prefixed (f-15-1 opc2) (f-18-3 opc3)) + sem) + ) +) + +(define-pmacro (bitsrc-insn op opc16-1 opc16-2 opc16-3 opc32-1 opc32-2 opc32-3 sem) + (begin + (bitsrc16-defn op opc16-1 opc16-2 opc16-3 sem) + (bitsrc32-defn op opc32-1 opc32-2 opc32-3 sem) + ) +) + +(define-pmacro (bitdst16-defn op opc1 opc2 opc3 opc4 opc5 opc6 sem) + (begin + (bit-insn-defn 16 op G bit16-16-basic (+ opc1 opc2 opc3 bit16-16-basic) sem) + (bit-insn-defn 16 op G bit16-16-16 (+ opc1 opc2 opc3 bit16-16-16) sem) + (bit-insn-defn 16 op S bit16-11-S (+ opc4 opc5 opc6 bit16-11-S) sem) + (bit-insn-defn 16 op G bit16-16-8 (+ opc1 opc2 opc3 bit16-16-8) sem) + ) +) + +(define-pmacro (bitdst32-defn op opc1 opc2 opc3 sem) + (begin + (bit-insn-defn 32 op X bit32-16-Unprefixed + (+ (f-0-4 opc1) bit32-16-Unprefixed (f-7-1 opc2) (f-10-3 opc3)) + sem) + ) +) + +(define-pmacro (bitdstnos-insn op opc16-1 opc16-2 opc16-3 opc32-1 opc32-2 opc32-3 sem) + (begin + (bitsrc16-defn op opc16-1 opc16-2 opc16-3 sem) + (bitdst32-defn op opc32-1 opc32-2 opc32-3 sem) + ) +) + +(define-pmacro (bitdst-insn op opc16-1 opc16-2 opc16-3 opc16-4 opc16-5 opc16-6 opc32-1 opc32-2 opc32-3 sem) + (begin + (bitdst16-defn op opc16-1 opc16-2 opc16-3 opc16-4 opc16-5 opc16-6 sem) + (bitdst32-defn op opc32-1 opc32-2 opc32-3 sem) + ) +) + +;============================================================= +; Bit condition +; +(define-pmacro (bitcond-insn-defn mach op bit-opnd cond-opnd encoding sem) + (dni (.sym op mach - bit-opnd - cond-opnd) + (.str op mach " " bit-opnd " " cond-opnd) + ((machine mach)) + (.str op "${" cond-opnd "} ${" bit-opnd "}") + encoding + (sem mach bit-opnd cond-opnd) + ()) +) + +(define-pmacro (bitcond16-defn op opc1 opc2 opc3 sem) + (begin + (bitcond-insn-defn 16 op bit16-16-basic cond16-16 (+ opc1 opc2 opc3 bit16-16-basic cond16-16) sem) + (bitcond-insn-defn 16 op bit16-16-16 cond16-32 (+ opc1 opc2 opc3 bit16-16-16 cond16-32) sem) + (bitcond-insn-defn 16 op bit16-16-8 cond16-24 (+ opc1 opc2 opc3 bit16-16-8 cond16-24) sem) + ) +) + +(define-pmacro (bitcond32-defn op opc1 opc2 opc3 sem) + (begin + (bitcond-insn-defn 32 op bit32-16-24-Unprefixed cond32-40 + (+ (f-0-4 opc1) bit32-16-24-Unprefixed (f-7-1 opc2) (f-10-3 opc3) cond32-40) + sem) + (bitcond-insn-defn 32 op bit32-16-16-Unprefixed cond32-32 + (+ (f-0-4 opc1) bit32-16-16-Unprefixed (f-7-1 opc2) (f-10-3 opc3) cond32-32) + sem) + (bitcond-insn-defn 32 op bit32-16-8-Unprefixed cond32-24 + (+ (f-0-4 opc1) bit32-16-8-Unprefixed (f-7-1 opc2) (f-10-3 opc3) cond32-24) + sem) + (bitcond-insn-defn 32 op bit32-basic-Unprefixed cond32-16 + (+ (f-0-4 opc1) bit32-basic-Unprefixed (f-7-1 opc2) (f-10-3 opc3) cond32-16) + sem) + ) +) + +(define-pmacro (bitcond-insn op opc16-1 opc16-2 opc16-3 opc32-1 opc32-2 opc32-3 sem) + (begin + (bitcond16-defn op opc16-1 opc16-2 opc16-3 sem) + (bitcond32-defn op opc32-1 opc32-2 opc32-3 sem) + ) +) + +;============================================================= +;<insn>.size #imm1,#imm2,dst -- for m32c +; +(define-pmacro (insn-imm1-imm2-dst-defn src1 src2 dstgroup xmode wstr op encoding sem) + (dni (.sym op 32 wstr - src1 - src2 - dstgroup) + (.str op 32 wstr "-" src1 "-" src2 "-" dstgroup "-" xmode) + ((machine 32)) + (.str op wstr " #${" src1 "},#${" src2 "},${dst32-" dstgroup "-" xmode "}") + encoding + (sem xmode src1 src2 (.sym dst32- dstgroup - xmode)) + ()) +) + +; m32c Prefixed variants +(define-pmacro (insn32-imm1-imm2-dst-Prefixed-defn xmode wstr wbit base1 base2 base3 base4 op opc1 opc2 opc3 sem) + (begin + (insn-imm1-imm2-dst-defn (.sym Imm-48- xmode) (.sym Imm- base4 - xmode) 24-24-Prefixed xmode wstr op + (+ (f-0-4 0) (f-4-4 1) (f-8-4 opc1) (f-18-2 opc2) (f-15-1 wbit) (f-20-4 opc3) + (.sym dst32-24-24-Prefixed- xmode) (.sym Imm-48- xmode) (.sym Imm- base4 - xmode)) + sem) + (insn-imm1-imm2-dst-defn (.sym Imm-40- xmode) (.sym Imm- base3 - xmode) 24-16-Prefixed xmode wstr op + (+ (f-0-4 0) (f-4-4 1) (f-8-4 opc1) (f-18-2 opc2) (f-15-1 wbit) (f-20-4 opc3) + (.sym dst32-24-16-Prefixed- xmode) (.sym Imm-40- xmode) (.sym Imm- base3 - xmode)) + sem) + (insn-imm1-imm2-dst-defn (.sym Imm-32- xmode) (.sym Imm- base2 - xmode) 24-8-Prefixed xmode wstr op + (+ (f-0-4 0) (f-4-4 1) (f-8-4 opc1) (f-18-2 opc2) (f-15-1 wbit) (f-20-4 opc3) + (.sym dst32-24-8-Prefixed- xmode) (.sym Imm-32- xmode) (.sym Imm- base2 - xmode)) + sem) + (insn-imm1-imm2-dst-defn (.sym Imm-24- xmode) (.sym Imm- base1 - xmode) basic-Prefixed xmode wstr op + (+ (f-0-4 0) (f-4-4 1) (f-8-4 opc1) (f-18-2 opc2) (f-15-1 wbit) (f-20-4 opc3) + (.sym dst32-basic-Prefixed- xmode) (.sym Imm-24- xmode) (.sym Imm- base1 - xmode)) + sem) + ) +) + +; m32c Unprefixed variants +(define-pmacro (insn32-imm1-imm2-dst-Unprefixed-defn xmode wstr wbit base1 base2 base3 base4 op opc1 opc2 opc3 sem) + (begin + (insn-imm1-imm2-dst-defn (.sym Imm-40- xmode) (.sym Imm- base4 - xmode) 16-24-Unprefixed xmode wstr op + (+ (f-0-4 opc1) (f-10-2 opc2) (f-7-1 wbit) (f-12-4 opc3) + (.sym dst32-16-24-Unprefixed- xmode) (.sym Imm-40- xmode) (.sym Imm- base4 - xmode)) + sem) + (insn-imm1-imm2-dst-defn (.sym Imm-32- xmode) (.sym Imm- base3 - xmode) 16-16-Unprefixed xmode wstr op + (+ (f-0-4 opc1) (f-10-2 opc2) (f-7-1 wbit) (f-12-4 opc3) + (.sym dst32-16-16-Unprefixed- xmode) (.sym Imm-32- xmode) (.sym Imm- base3 - xmode)) + sem) + (insn-imm1-imm2-dst-defn (.sym Imm-24- xmode) (.sym Imm- base2 - xmode) 16-8-Unprefixed xmode wstr op + (+ (f-0-4 opc1) (f-10-2 opc2) (f-7-1 wbit) (f-12-4 opc3) + (.sym dst32-16-8-Unprefixed- xmode) (.sym Imm-24- xmode) (.sym Imm- base2 - xmode)) + sem) + (insn-imm1-imm2-dst-defn (.sym Imm-16- xmode) (.sym Imm- base1 - xmode) basic-Unprefixed xmode wstr op + (+ (f-0-4 opc1) (f-10-2 opc2) (f-7-1 wbit) (f-12-4 opc3) + (.sym dst32-basic-Unprefixed- xmode) (.sym Imm-16- xmode) (.sym Imm- base1 - xmode)) + sem) + ) +) + +(define-pmacro (insn-imm1-imm2-dst-Prefixed op opc32-1 opc32-2 opc32-3 sem) + (begin + (insn32-imm1-imm2-dst-Prefixed-defn QI .b 0 32 40 48 56 op opc32-1 opc32-2 opc32-3 sem) + (insn32-imm1-imm2-dst-Prefixed-defn HI .w 1 40 48 56 64 op opc32-1 opc32-2 opc32-3 sem) + ) +) +(define-pmacro (insn-imm1-imm2-dst-Unprefixed op opc32-1 opc32-2 opc32-3 sem) + (begin + (insn32-imm1-imm2-dst-Unprefixed-defn QI .b 0 24 32 40 48 op opc32-1 opc32-2 opc32-3 sem) + (insn32-imm1-imm2-dst-Unprefixed-defn HI .w 1 32 40 48 56 op opc32-1 opc32-2 opc32-3 sem) + ) +) + +;============================================================= +; Insn definitions +;------------------------------------------------------------- +; abs - absolute +;------------------------------------------------------------- + +(define-pmacro (abs-sem mode dst) + (sequence ((mode result)) + (set result (abs mode dst)) + (set obit (eq result dst)) + (set-z-and-s result) + (set dst result)) +) +(unary-insn abs (f-0-4 7) (f-4-3 3) (f-8-4 #xF) #xA #x1 #xF abs-sem) + +;------------------------------------------------------------- +; adcf - addition carry flag +;------------------------------------------------------------- + +(define-pmacro (adcf-sem mode dst) + (sequence ((mode result)) + (set result (addc mode dst 0 cbit)) + (set obit (add-oflag mode dst 0 cbit)) + (set cbit (add-cflag mode dst 0 cbit)) + (set-z-and-s result) + (set dst result)) +) +(unary-insn adcf (f-0-4 7) (f-4-3 3) (f-8-4 #xE) #xB #x1 #xE adcf-sem) + +;------------------------------------------------------------- +; add - binary addition +;------------------------------------------------------------- + +(define-pmacro (add-sem mode src1 dst) + (sequence ((mode result)) + (set result (add mode src1 dst)) + (set obit (add-oflag mode src1 dst 0)) + (set cbit (add-cflag mode src1 dst 0)) + (set-z-and-s result) + (set dst result)) +) + +; add.L:G #imm32,dst (m32 #2) +(binary-arith32-imm-dst-defn SI SI .l 0 add G #x8 #x3 #x1 add-sem) +; add.size:G #imm,dst (m16 #1 m32 #1) +(binary-arith-imm-dst add G (f-0-4 7) (f-4-3 3) (f-8-4 4) #x8 #x2 #xE add-sem) +; add.size:Q #imm4,dst (m16 #2 m32 #3) +(binary-arith-imm4-dst add (f-0-4 #xC) (f-4-3 4) #x7 #x3 add-sem) +(binary-arith32-imm4-dst-defn SI .l 1 0 add #x7 #x3 add-sem) +; add.b:S #imm8,dst3 (m16 #3) +(binary-arith16-b-S-imm8-dst3 add ".b" (f-0-4 8) (f-4-1 0) add-sem) +; add.BW:Q #imm4,sp (m16 #7) +(binary-arith16-Q-sp add (f-0-4 7) (f-4-4 #xD) (f-8-4 #xB) add-sem) +(dnmi add16-bQ-sp "add16-bQ-sp" () + "add.b:q #${Imm-12-s4},sp" + (emit add16-wQ-sp Imm-12-s4)) +; add.BW:G #imm,sp (m16 #6) +(binary-arith16-G-sp add (f-0-4 7) (f-4-3 6) (f-8-4 #xE) (f-12-4 #xB) add-sem) +; add.BW:G src,dst (m16 #4 m32 #6) +(binary-arith-src-dst add G (f-0-4 #xA) (f-4-3 0) #x1 #x8 add-sem) +; add.B.S src2,r0l/r0h (m16 #5) +(binary-arith16-b-S-src2 add (f-0-4 2) (f-4-1 0) add-sem) +; add.L:G src,dst (m32 #7) +(binary-arith32-src-dst-defn SI SI .l 1 add G #x1 #x2 add-sem) +; add.L:S #imm{1,2},A0/A1 (m32 #5) +(binary-arith32-l-s-imm1-an add (f-0-2 2) (f-3-4 6) add-sem) +; add.L:Q #imm3,sp (m32 #9) +(binary-arith32-l-q-imm3-sp add (f-0-2 1) (f-4-3 1) add-sem) +; add.L:S #imm8,sp (m32 #10) +(binary-arith32-l-s-imm8-sp add (f-0-4 #xb) (f-4-4 6) (f-8-4 0) (f-12-4 3) add-sem) +; add.L:G #imm16,sp (m32 #8) +(binary-arith32-l-g-imm16-sp add (f-0-4 #xb) (f-4-4 6) (f-8-4 1) (f-12-4 3) add-sem) +; add.BW:S #imm,dst2 (m32 #4) +(binary-arith32-s-imm-dst QI .b 0 add #x0 #x3 add-sem) +(binary-arith32-s-imm-dst HI .w 1 add #x0 #x3 add-sem) + +;------------------------------------------------------------- +; adc - binary add with carry +;------------------------------------------------------------- + +(define-pmacro (addc-sem mode src dst) + (sequence ((mode result)) + (set result (addc mode src dst cbit)) + (set obit (add-oflag mode src dst cbit)) + (set cbit (add-cflag mode src dst cbit)) + (set-z-and-s result) + (set dst result)) +) + +; adc.size:G #imm,dst +(binary-arith16-imm-dst-defn QI QI .b 0 adc X (f-0-4 7) (f-4-3 3) (f-8-4 6) addc-sem) +(binary-arith16-imm-dst-defn HI HI .w 1 adc X (f-0-4 7) (f-4-3 3) (f-8-4 6) addc-sem) +(binary-arith32-imm-dst-Prefixed QI QI .b 0 adc X #x8 #x2 #xE addc-sem) +(binary-arith32-imm-dst-Prefixed HI HI .w 1 adc X #x8 #x2 #xE addc-sem) + +; adc.BW:G src,dst +(binary-arith16-src-dst-defn QI QI .b 0 adc X (f-0-4 #xB) (f-4-3 0) addc-sem) +(binary-arith16-src-dst-defn HI HI .w 1 adc X (f-0-4 #xB) (f-4-3 0) addc-sem) +(binary-arith32-src-dst-Prefixed QI QI .b 0 adc X #x1 #x4 addc-sem) +(binary-arith32-src-dst-Prefixed HI HI .w 1 adc X #x1 #x4 addc-sem) + +;------------------------------------------------------------- +; dadc - decimal add with carry +; dadd - decimal addition +;------------------------------------------------------------- + +(define-pmacro (dadc-sem mode src dst) + (sequence ((mode result)) + (set result (subc mode dst src (not cbit))) + (set cbit (sub-cflag mode dst src (not cbit))) + (set-z-and-s result) + (set dst result)) +) + +(define-pmacro (decimal-subtraction16-insn op opc1 opc2) + (begin + ; op.b #imm8,r0l + (dni (.sym op 16.b-imm8) + (.str op ".b #imm8") + ((machine 16)) + (.str op ".b #${Imm-16-QI},r0l") + (+ (f-0-4 #x7) (f-4-4 #xC) (f-8-4 #xE) (f-12-4 opc1) Imm-16-QI) + ((.sym op -sem) QI Imm-16-QI R0l) + ()) + ; op.w #imm16,r0 + (dni (.sym op 16.w-imm16) + (.str op ".b #imm16") + ((machine 16)) + (.str op ".w #${Imm-16-HI},r0") + (+ (f-0-4 #x7) (f-4-4 #xD) (f-8-4 #xE) (f-12-4 opc1) Imm-16-HI) + ((.sym op -sem) HI Imm-16-HI R0) + ()) + ; op.b #r0h,r0l + (dni (.sym op 16.b-r0h-r0l) + (.str op ".b r0h,r0l") + ((machine 16)) + (.str op ".b r0h,r0l") + (+ (f-0-4 #x7) (f-4-4 #xC) (f-8-4 #xE) (f-12-4 opc2)) + ((.sym op -sem) QI R0h R0l) + ()) + ; op.w #r1,r0 + (dni (.sym op 16.w-r1-r0) + (.str op ".b r1,r0") + ((machine 16)) + (.str op ".w r1,r0") + (+ (f-0-4 #x7) (f-4-4 #xD) (f-8-4 #xE) (f-12-4 opc2)) + ((.sym op -sem) HI R1 R0) + ()) + ) +) + +; dadc for m16c +(decimal-subtraction16-insn dadc #xE #x6 ) + +; dadc.size #imm,dst +(binary-arith32-imm-dst-Prefixed QI QI .b 0 dadc X #x8 #x0 #xE dadc-sem) +(binary-arith32-imm-dst-Prefixed HI HI .w 1 dadc X #x8 #x0 #xE dadc-sem) +; dadc.BW src,dst +(binary-arith32-src-dst-Prefixed QI QI .b 0 dadc X #x1 #x8 dadc-sem) +(binary-arith32-src-dst-Prefixed HI HI .w 1 dadc X #x1 #x8 dadc-sem) + +(define-pmacro (dadd-sem mode src dst) + (sequence ((mode result)) + (set result (subc mode dst src 0)) + (set cbit (sub-cflag mode dst src 0)) + (set-z-and-s result) + (set dst result)) +) + +; dadd for m16c +(decimal-subtraction16-insn dadd #xC #x4) + +; dadd.size #imm,dst +(binary-arith32-imm-dst-Prefixed QI QI .b 0 dadd X #x8 #x1 #xE dadd-sem) +(binary-arith32-imm-dst-Prefixed HI HI .w 1 dadd X #x8 #x1 #xE dadd-sem) +; dadd.BW src,dst +(binary-arith32-src-dst-Prefixed QI QI .b 0 dadd X #x1 #x0 dadd-sem) +(binary-arith32-src-dst-Prefixed HI HI .w 1 dadd X #x1 #x0 dadd-sem) + +;-------------------------------------------------------------; +; addx - Add extend sign with no carry +;-------------------------------------------------------------; + +(define-pmacro (addx-sem mode src dst) + (sequence ((SI source) (SI result)) + (set source (zext SI (trunc QI src))) + (set result (add SI source dst)) + (set obit (add-oflag SI source dst 0)) + (set cbit (add-cflag SI source dst 0)) + (set-z-and-s result) + (set dst result)) +) + +; addx #imm,dst +(binary-arith32-imm-dst-defn QI SI "" 0 addx X #x8 #x1 #x1 addx-sem) +; addx src,dst +(binary-arith32-src-dst-defn QI SI "" 0 addx X #x1 #x2 addx-sem) + +;------------------------------------------------------------- +; adjnz - Add/Sub and branch if not zero +;------------------------------------------------------------- + +(define-pmacro (arith-jnz-sem mode src dst label) + (sequence ((mode result)) + (set result (add mode src dst)) + (set dst result) + (if (ne result 0) + (set pc label))) +) + +; adjnz.size #imm4,dst,label +(arith-jnz-imm4-dst adjnz s4 (f-0-4 #xF) (f-4-3 4) #xf #x1 arith-jnz-sem) + +;------------------------------------------------------------- +; and - binary and +;------------------------------------------------------------- + +(define-pmacro (and-sem mode src1 dst) + (sequence ((mode result)) + (set result (and mode src1 dst)) + (set-z-and-s result) + (set dst result)) +) + +; and.size:G #imm,dst (m16 #1 m32 #1) +(binary-arith-imm-dst and G (f-0-4 7) (f-4-3 3) (f-8-4 2) #x8 #x3 #xF and-sem) +; and.b:S #imm8,dst3 (m16 #2) +(binary-arith16-b-S-imm8-dst3 and ".b" (f-0-4 9) (f-4-1 0) and-sem) +; and.BW:G src,dst (m16 #3 m32 #3) +(binary-arith-src-dst and G (f-0-4 #x9) (f-4-3 0) #x1 #xD and-sem) +; and.B.S src2,r0l/r0h (m16 #4) +(binary-arith16-b-S-src2 and (f-0-4 1) (f-4-1 0) and-sem) +; and.BW:S #imm,dst2 (m32 #2) +(binary-arith32-s-imm-dst QI .b 0 and #x1 #x6 and-sem) +(binary-arith32-s-imm-dst HI .w 1 and #x1 #x6 and-sem) + +;------------------------------------------------------------- +; band - bit and +;------------------------------------------------------------- + +(define-pmacro (band-sem src) + (set cbit (and src cbit)) +) +(bitsrc-insn band (f-0-4 7) (f-4-4 #xE) (f-8-4 4) #xD #x0 #x1 band-sem) + +;------------------------------------------------------------- +; bclr - bit clear +;------------------------------------------------------------- + +(define-pmacro (bclr-sem dst) + (set dst 0) +) +(bitdst-insn bclr (f-0-4 7) (f-4-4 #xE) (f-8-4 8) (f-0-2 1) (f-2-2 0) (f-4-1 0) #xD #x0 #x6 bclr-sem) + +;------------------------------------------------------------- +; bitindex - bit index +;------------------------------------------------------------- + +(define-pmacro (bitindex-sem mode dst) + (set BitIndex dst) +) +(unary-insn-defn 32 16-Unprefixed QI .b bitindex + (+ (f-0-4 #xC) (f-7-1 0) dst32-16-Unprefixed-QI (f-10-2 #x2) (f-12-4 #xE)) + bitindex-sem) +(unary-insn-defn 32 16-Unprefixed HI .w bitindex + (+ (f-0-4 #xC) (f-7-1 1) dst32-16-Unprefixed-HI (f-10-2 #x2) (f-12-4 #xE)) + bitindex-sem) + +;------------------------------------------------------------- +; bmCnd - bit move condition +;------------------------------------------------------------- + +(define-pmacro (test-condition16 cond) + (case UQI cond + ((#x00) (trunc BI cbit)) + ((#x01) (not (or cbit zbit))) + ((#x02) (trunc BI zbit)) + ((#x03) (trunc BI sbit)) + ((#x04) (or zbit (xor sbit obit))) + ((#x05) (trunc BI obit)) + ((#x06) (xor sbit obit)) + ((#xf8) (not cbit)) + ((#xf9) (or cbit zbit)) + ((#xfa) (not zbit)) + ((#xfb) (not sbit)) + ((#xfc) (not (or zbit (xor sbit obit)))) + ((#xfd) (not obit)) + ((#xfe) (not (xor sbit obit))) + (else (const BI 0)) + ) +) + +(define-pmacro (test-condition32 cond) + (case UQI cond + ((#x00) (not cbit)) + ((#x01) (or cbit zbit)) + ((#x02) (not zbit)) + ((#x03) (not sbit)) + ((#x04) (not obit)) + ((#x05) (not (or zbit (xor sbit obit)))) + ((#x06) (not (xor sbit obit))) + ((#x08) (trunc BI cbit)) + ((#x09) (not (or cbit zbit))) + ((#x0a) (trunc BI zbit)) + ((#x0b) (trunc BI sbit)) + ((#x0c) (trunc BI obit)) + ((#x0d) (or zbit (xor sbit obit))) + ((#x0e) (xor sbit obit)) + (else (const BI 0)) + ) +) + +(define-pmacro (bitcond-sem mach op cond) + (if ((.sym test-condition mach) cond) + (set op 1) + (set op 0)) +) +(bitcond-insn bm (f-0-4 7) (f-4-4 #xE) (f-8-4 2) #xD #x0 #x2 bitcond-sem) + +(dni bm16-c + "bm16 C" + ((machine 16)) + "bm$cond16c c" + (+ (f-0-4 #x7) (f-4-4 #xD) (f-8-4 #xD) cond16c) + (bitcond-sem 16 cbit cond16c) + ()) + +(dni bm32-c + "bm32 C" + ((machine 32)) + "bm$cond32 c" + (+ (f-0-4 #xD) (f-4-4 #x9) (f-8-1 0) (f-10-3 5) cond32) + (bitcond-sem 32 cbit cond32) + ()) + +;------------------------------------------------------------- +; bnand +;------------------------------------------------------------- + +(define-pmacro (bnand-sem src) + (set cbit (and (inv src) cbit)) +) +(bitsrc-insn bnand (f-0-4 7) (f-4-4 #xE) (f-8-4 5) #xD #x0 #x3 bnand-sem) + +;------------------------------------------------------------- +; bnor +;------------------------------------------------------------- + +(define-pmacro (bnor-sem src) + (set cbit (or (inv src) cbit)) +) +(bitsrc-insn bnor (f-0-4 7) (f-4-4 #xE) (f-8-4 7) #xD #x0 #x6 bnor-sem) + +;------------------------------------------------------------- +; bnot +;------------------------------------------------------------- + +(define-pmacro (bnot-sem dst) + (set dst (inv dst)) +) +(bitdst-insn bnot (f-0-4 7) (f-4-4 #xE) (f-8-4 #xA) (f-0-2 1) (f-2-2 1) (f-4-1 0) #xD #x0 #x3 bnot-sem) + +;------------------------------------------------------------- +; bntst +;------------------------------------------------------------- + +(define-pmacro (bntst-sem src) + (set cbit (inv src)) + (set zbit (inv src)) +) +(bitsrc-insn bntst (f-0-4 7) (f-4-4 #xE) (f-8-4 3) #xD #x0 #x0 bntst-sem) + +;------------------------------------------------------------- +; bnxor +;------------------------------------------------------------- + +(define-pmacro (bnxor-sem src) + (set cbit (xor (inv src) cbit)) +) +(bitsrc-insn bnxor (f-0-4 7) (f-4-4 #xE) (f-8-4 #xD) #xD #x0 #x7 bnxor-sem) + +;------------------------------------------------------------- +; bor +;------------------------------------------------------------- + +(define-pmacro (bor-sem src) + (set cbit (or src cbit)) +) +(bitsrc-insn bor (f-0-4 7) (f-4-4 #xE) (f-8-4 #x6) #xD #x0 #x4 bor-sem) + +;------------------------------------------------------------- +; brk +;------------------------------------------------------------- + +(dni brk16 + "brk" + ((machine 16)) + "brk" + (+ (f-0-4 #x0) (f-4-4 #x0)) + (nop) + ()) + +(dni brk32 + "brk" + ((machine 32)) + "brk" + (+ (f-0-4 #x0) (f-4-4 #x0)) + (nop) + ()) + +;------------------------------------------------------------- +; brk2 +;------------------------------------------------------------- + +(dni brk232 + "brk2" + ((machine 32)) + "brk2" + (+ (f-0-4 #x0) (f-4-4 #x8)) + (nop) + ()) + +;------------------------------------------------------------- +; bset +;------------------------------------------------------------- + +(define-pmacro (bset-sem dst) + (set dst 1) +) +(bitdst-insn bset (f-0-4 7) (f-4-4 #xE) (f-8-4 9) (f-0-2 1) (f-2-2 0) (f-4-1 1) #xD #x0 #x7 bset-sem) + +;------------------------------------------------------------- +; btst +;------------------------------------------------------------- + +(define-pmacro (btst-sem dst) + (set zbit (inv dst)) + (set cbit dst) +) +(bitdst16-defn btst (f-0-4 7) (f-4-4 #xE) (f-8-4 #xB) (f-0-2 1) (f-2-2 1) (f-4-1 1) btst-sem) + +(bit-insn-defn 32 btst G bit32-16-Unprefixed + (+ (f-0-4 #xD) bit32-16-Unprefixed (f-7-1 #x0) (f-10-3 #x0)) + btst-sem) + +(dni btst.s "btst:s" ((machine 32)) + "btst:s ${Bit3-S},${Dsp-8-u16}" + (+ (f-0-2 #x0) (f-4-3 #x5) Bit3-S Dsp-8-u16) + () ()) + +;------------------------------------------------------------- +; btstc +;------------------------------------------------------------- + +(define-pmacro (btstc-sem dst) + (set zbit (inv dst)) + (set cbit dst) + (set dst (const 0)) +) +(bitdstnos-insn btstc (f-0-4 7) (f-4-4 #xE) (f-8-4 #x0) #xD #x0 #x4 btstc-sem) + +;------------------------------------------------------------- +; btsts +;------------------------------------------------------------- + +(define-pmacro (btsts-sem dst) + (set zbit (inv dst)) + (set cbit dst) + (set dst (const 0)) +) +(bitdstnos-insn btsts (f-0-4 7) (f-4-4 #xE) (f-8-4 #x1) #xD #x0 #x5 btsts-sem) + +;------------------------------------------------------------- +; bxor +;------------------------------------------------------------- + +(define-pmacro (bxor-sem src) + (set cbit (xor src cbit)) +) +(bitsrc-insn bxor (f-0-4 7) (f-4-4 #xE) (f-8-4 #xC) #xD #x0 #x5 bxor-sem) + +;------------------------------------------------------------- +; clip +;------------------------------------------------------------- + +(define-pmacro (clip-sem mode imm1 imm2 dest) + (sequence () + (if (gt mode imm1 dest) + (set dest imm1)) + (if (lt mode imm2 dest) + (set dest imm2))) +) + +(insn-imm1-imm2-dst-Prefixed clip #x8 #x3 #xE clip-sem) + +;------------------------------------------------------------- +; cmp - binary compare +;------------------------------------------------------------- + +(define-pmacro (cmp-sem mode src1 dst) + (sequence ((mode result)) + (set result (sub mode dst src1)) + (set obit (sub-oflag mode dst src1 0)) + (set cbit (not (sub-cflag mode dst src1 0))) + (set-z-and-s result)) +) + +; cmp.L:G #imm32,dst (m32 #2) +(binary-arith32-imm-dst-defn SI SI .l 0 cmp G #xA #x3 #x1 cmp-sem) +; cmp.size:G #imm,dst (m16 #1 m32 #1) +(binary-arith-imm-dst cmp G (f-0-4 7) (f-4-3 3) (f-8-4 8) #x9 #x2 #xE cmp-sem) +; cmp.size:Q #imm4,dst (m16 #2 m32 #3) +(binary-arith-imm4-dst cmp (f-0-4 #xD) (f-4-3 0) #x7 #x1 cmp-sem) +; cmp.b:S #imm8,dst3 (m16 #3) +(binary-arith16-b-S-imm8-dst3 cmp ".b" (f-0-4 #xE) (f-4-1 0) cmp-sem) +; cmp.BW:G src,dst (m16 #4 m32 #5) +(binary-arith-src-dst cmp G (f-0-4 #xC) (f-4-3 0) #x1 #x6 cmp-sem) +; cmp.B.S src2,r0l/r0h (m16 #5) +(binary-arith16-b-S-src2 cmp (f-0-4 3) (f-4-1 1) cmp-sem) +; cmp.L:G src,dst (m32 #6) +(binary-arith32-src-dst-defn SI SI .l 1 cmp G #x1 #x1 cmp-sem) +; cmp.BW:S #imm,dst2 (m32 #4) +(binary-arith32-s-imm-dst QI .b 0 cmp #x1 #x3 cmp-sem) +(binary-arith32-s-imm-dst HI .w 1 cmp #x1 #x3 cmp-sem) +; cmp.BW:s src2,r0[l] (m32 #7) +(binary-arith32-S-src2 cmp QI .b 0 (f-0-2 1) (f-4-3 0) cmp-sem) +(binary-arith32-S-src2 cmp HI .w 1 (f-0-2 1) (f-4-3 0) cmp-sem) + +;------------------------------------------------------------- +; cmpx - binary compare extend sign +;------------------------------------------------------------- + +(define-pmacro (cmpx-sem mode src1 dst) + (sequence ((mode result)) + (set result (sub mode dst (ext mode src1))) + (set obit (sub-oflag mode dst (ext mode src1) 0)) + (set cbit (sub-cflag mode dst (ext mode src1) 0)) + (set-z-and-s result)) +) + +(binary-arith32-imm-dst-defn QI SI "" 0 cmpx X #xA #x1 #x1 cmpx-sem) + +;------------------------------------------------------------- +; dec - decrement +;------------------------------------------------------------- + +(define-pmacro (dec-sem mode dest) + (sequence ((mode result)) + (set result (sub mode dest 1)) + (set-z-and-s result) + (set dest result)) +) + +(dni dec16.b + "dec.b Dst16-3-S-8" + ((machine 16)) + "dec.b ${Dst16-3-S-8}" + (+ (f-0-4 #xA) (f-4-1 #x1) Dst16-3-S-8) + (dec-sem QI Dst16-3-S-8) + ()) + +(dni dec16.w + "dec.w Dst16An-S" + ((machine 16)) + "dec.w ${Dst16An-S}" + (+ (f-0-4 #xF) (f-5-3 #x2) Dst16An-S) + (dec-sem HI Dst16An-S) + ()) + +(unary32-defn QI .b 0 dec #xB #x0 #xE dec-sem) +(unary32-defn HI .w 1 dec #xB #x0 #xE dec-sem) + +;------------------------------------------------------------- +; div - divide +; divu - divide unsigned +; divx - divide extension +;------------------------------------------------------------- + +; div.BW #imm +(div-imm div div mod SI 127 -128 32767 -32768 (f-0-4 #x7) (f-4-3 6) (f-8-4 #xE) (f-12-4 #x1) #xB #x0 #x2 #x3 div-sem) +(div-imm divu udiv umod USI 255 0 65535 0 (f-0-4 #x7) (f-4-3 6) (f-8-4 #xE) (f-12-4 #x0) #xB #x0 #x0 #x3 div-sem) +(div-imm divx div mod SI 127 -128 32767 -32768 (f-0-4 #x7) (f-4-3 6) (f-8-4 #xE) (f-12-4 #x3) #xB #x2 #x2 #x3 div-sem) +; div.BW src +(div-src div div mod SI 127 -128 32767 -32768 (f-0-4 #x7) (f-4-3 3) (f-8-4 #xD) #x8 #x1 #xE div-sem) +(div-src divu udiv umod USI 255 0 65535 0 (f-0-4 #x7) (f-4-3 3) (f-8-4 #xC) #x8 #x0 #xE div-sem) +(div-src divx div mod SI 127 -128 32767 -32768 (f-0-4 #x7) (f-4-3 3) (f-8-4 #x9) #x9 #x1 #xE div-sem) + +(div-src-defn 32 .l div dst32-24-Prefixed-SI + (+ (f-0-4 0) (f-4-4 1) (f-8-4 #xA) (f-15-1 1) (f-18-2 #x1) (f-20-4 #xf) dst32-24-Prefixed-SI) + div mod SI R2R0 R2R0 NoRemainder #x7fffffff (neg SI #x80000000) + div-sem) +(div-src-defn 32 .l divu dst32-24-Prefixed-SI + (+ (f-0-4 0) (f-4-4 1) (f-8-4 #xA) (f-15-1 1) (f-18-2 #x0) (f-20-4 #xf) dst32-24-Prefixed-SI) + udiv umod USI R2R0 R2R0 NoRemainder #x80000000 0 + div-sem) +(div-src-defn 32 .l divx dst32-24-Prefixed-SI + (+ (f-0-4 0) (f-4-4 1) (f-8-4 #xA) (f-15-1 1) (f-18-2 #x2) (f-20-4 #xf) dst32-24-Prefixed-SI) + div mod SI R2R0 R2R0 NoRemainder #x7fffffff (neg SI #x80000000) + div-sem) + +;------------------------------------------------------------- +; dsbb - decimal subtraction with borrow +; dsub - decimal subtraction +;------------------------------------------------------------- + +(define-pmacro (dsbb-sem mode src dst) + (sequence ((mode result)) + (set result (subc mode dst src (not cbit))) + (set cbit (sub-cflag mode dst src (not cbit))) + (set-z-and-s result) + (set dst result)) +) + +; dsbb for m16c +(decimal-subtraction16-insn dsbb #xF #x7) + +; dsbb.size #imm,dst +(binary-arith32-imm-dst-Prefixed QI QI .b 0 dsbb X #x9 #x0 #xE dsbb-sem) +(binary-arith32-imm-dst-Prefixed HI HI .w 1 dsbb X #x9 #x0 #xE dsbb-sem) +; dsbb.BW src,dst +(binary-arith32-src-dst-Prefixed QI QI .b 0 dsbb X #x1 #xA dsbb-sem) +(binary-arith32-src-dst-Prefixed HI HI .w 1 dsbb X #x1 #xA dsbb-sem) + +(define-pmacro (dsub-sem mode src dst) + (sequence ((mode result)) + (set result (subc mode dst src 0)) + (set cbit (sub-cflag mode dst src 0)) + (set-z-and-s result) + (set dst result)) +) + +; dsub for m16c +(decimal-subtraction16-insn dsub #xD #x5) + +; dsub.size #imm,dst +(binary-arith32-imm-dst-Prefixed QI QI .b 0 dsub X #x9 #x1 #xE dsub-sem) +(binary-arith32-imm-dst-Prefixed HI HI .w 1 dsub X #x9 #x1 #xE dsub-sem) +; dsub.BW src,dst +(binary-arith32-src-dst-Prefixed QI QI .b 0 dsub X #x1 #x2 dsub-sem) +(binary-arith32-src-dst-Prefixed HI HI .w 1 dsub X #x1 #x2 dsub-sem) + +;------------------------------------------------------------- +; sub - binary subtraction +;------------------------------------------------------------- + +(define-pmacro (sub-sem mode src1 dst) + (sequence ((mode result)) + (set result (sub mode dst src1)) + (set obit (sub-oflag mode dst src1 0)) + (set cbit (sub-cflag mode dst src1 0)) + (set dst result) + (set-z-and-s result))) + +; sub.size:G #imm,dst (m16 #1 m32 #1) +(binary-arith-imm-dst sub G (f-0-4 7) (f-4-3 3) (f-8-4 5) #x8 #x3 #xE sub-sem) +; sub.b:S #imm8,dst3 (m16 #2) +(binary-arith16-b-S-imm8-dst3 sub ".b" (f-0-4 8) (f-4-1 1) sub-sem) +; sub.BW:G src,dst (m16 #3 m32 #4) +(binary-arith-src-dst sub G (f-0-4 #xA) (f-4-3 4) #x1 #xA sub-sem) +; sub.B.S src2,r0l/r0h (m16 #4) +(binary-arith16-b-S-src2 sub (f-0-4 2) (f-4-1 1) sub-sem) +; sub.L:G #imm32,dst (m32 #2) +(binary-arith32-imm-dst-defn SI SI .l 0 sub G #x9 #x3 #x1 sub-sem) +; sub.BW:S #imm,dst2 (m32 #3) +(binary-arith32-s-imm-dst QI .b 0 sub #x0 #x7 sub-sem) +(binary-arith32-s-imm-dst HI .w 1 sub #x0 #x7 sub-sem) +; sub.L:G src,dst (m32 #5) +(binary-arith32-src-dst-defn SI SI .l 1 sub G #x1 #x0 sub-sem) + +;------------------------------------------------------------- +; enter - enter function +; exitd - exit and deallocate stack frame +;------------------------------------------------------------- + +(define-pmacro (enter16-sem mach amt) + (sequence () + (set (reg h-sp) (sub (reg h-sp) 2)) + (set (mem16 HI (reg h-sp)) (reg h-fb)) + (set (reg h-fb) (reg h-sp)) + (set (reg h-sp) (sub (reg h-sp) amt)))) + +(define-pmacro (exit16-sem mach) + (sequence ((SI newpc)) + (set (reg h-sp) (reg h-fb)) + (set (reg h-fb) (mem16 HI (reg h-sp))) + (set (reg h-sp) (add (reg h-sp) 2)) + (set newpc (mem16 HI (reg h-sp))) + (set (reg h-sp) (add (reg h-sp) 2)) + (set newpc (or newpc (sll (mem16 QI (reg h-sp)) (const 16)))) + (set (reg h-sp) (add (reg h-sp) 1)) + (set pc newpc))) + +(define-pmacro (enter32-sem mach amt) + (sequence () + (set (reg h-sp) (sub (reg h-sp) 4)) + (set (mem32 SI (reg h-sp)) (reg h-fb)) + (set (reg h-fb) (reg h-sp)) + (set (reg h-sp) (sub (reg h-sp) amt)))) + +(define-pmacro (exit32-sem mach) + (sequence ((SI newpc)) + (set (reg h-sp) (reg h-fb)) + (set (reg h-fb) (mem32 SI (reg h-sp))) + (set (reg h-sp) (add (reg h-sp) 4)) + (set newpc (mem32 SI (reg h-sp))) + (set (reg h-sp) (add (reg h-sp) 4)) + (set pc newpc))) + +(dni enter16 "enter #Imm-16-QI" ((machine 16)) + ("enter #${Dsp-16-u8}") + (+ (f-0-4 7) (f-4-4 #xC) (f-8-4 #xF) (f-12-4 2) Dsp-16-u8) + (enter16-sem 16 Dsp-16-u8) + ()) + +(dni exitd16 "exitd" ((machine 16)) + ("exitd") + (+ (f-0-4 7) (f-4-4 #xD) (f-8-4 #xF) (f-12-4 2)) + (exit16-sem 16) + ()) + +(dni enter32 "enter #Imm-8-QI" ((machine 32)) + ("enter #${Dsp-8-u8}") + (+ (f-0-4 #xE) (f-4-4 #xC) Dsp-8-u8) + (enter32-sem 32 Dsp-8-u8) + ()) + +(dni exitd32 "exitd" ((machine 32)) + ("exitd") + (+ (f-0-4 #xF) (f-4-4 #xC)) + (exit32-sem 32) + ()) + +;------------------------------------------------------------- +; fclr - flag register clear +; fset - flag register set +;------------------------------------------------------------- + +(define-pmacro (set-flags-sem flag) + (sequence ((SI tmp)) + (case DFLT flag + ((#x0) (set cbit 1)) + ((#x1) (set dbit 1)) + ((#x2) (set zbit 1)) + ((#x3) (set sbit 1)) + ((#x4) (set bbit 1)) + ((#x5) (set obit 1)) + ((#x6) (set ibit 1)) + ((#x7) (set ubit 1))) + ) + ) + +(define-pmacro (clear-flags-sem flag) + (sequence ((SI tmp)) + (case DFLT flag + ((#x0) (set cbit 0)) + ((#x1) (set dbit 0)) + ((#x2) (set zbit 0)) + ((#x3) (set sbit 0)) + ((#x4) (set bbit 0)) + ((#x5) (set obit 0)) + ((#x6) (set ibit 0)) + ((#x7) (set ubit 0))) + ) + ) + +(dni fclr16 "fclr flag" ((machine 16)) + ("fclr ${flags16}") + (+ (f-0-4 #xE) (f-4-4 #xB) (f-8-1 0) flags16 (f-12-4 5)) + (clear-flags-sem flags16) + ()) + +(dni fset16 "fset flag" ((machine 16)) + ("fset ${flags16}") + (+ (f-0-4 #xE) (f-4-4 #xB) (f-8-1 0) flags16 (f-12-4 4)) + (set-flags-sem flags16) + ()) + +(dni fclr "fclr" ((machine 32)) + ("fclr ${flags32}") + (+ (f-0-4 #xD) (f-4-4 3) (f-8-4 #xE) (f-12-1 1) flags32) + (clear-flags-sem flags32) + ()) + +(dni fset "fset" ((machine 32)) + ("fset ${flags32}") + (+ (f-0-4 #xD) (f-4-4 1) (f-8-4 #xE) (f-12-1 1) flags32) + (set-flags-sem flags32) + ()) + +;------------------------------------------------------------- +; inc - increment +;------------------------------------------------------------- + +(define-pmacro (inc-sem mode dest) + (sequence ((mode result)) + (set result (add mode dest 1)) + (set-z-and-s result) + (set dest result)) +) + +(dni inc16.b + "inc.b Dst16-3-S-8" + ((machine 16)) + "inc.b ${Dst16-3-S-8}" + (+ (f-0-4 #xA) (f-4-1 #x0) Dst16-3-S-8) + (inc-sem QI Dst16-3-S-8) + ()) + +(dni inc16.w + "inc.w Dst16An-S" + ((machine 16)) + "inc.w ${Dst16An-S}" + (+ (f-0-4 #xB) (f-5-3 #x2) Dst16An-S) + (inc-sem HI Dst16An-S) + ()) + +(unary32-defn QI .b 0 inc #xA #x0 #xE inc-sem) +(unary32-defn HI .w 1 inc #xA #x0 #xE inc-sem) + +;------------------------------------------------------------- +; freit - fast return from interrupt (m32) +; int - interrupt +; into - interrupt on overflow +;------------------------------------------------------------- + +; ??? semantics +(dni freit32 "FREIT" ((machine 32)) + ("freit") + (+ (f-0-4 9) (f-4-4 #xF)) + (nop) + ()) + +(dni int16 "int Dsp-10-u6" ((machine 16)) + ("int #${Dsp-10-u6}") + (+ (f-0-4 #xE) (f-4-4 #xB) (f-8-2 3) Dsp-10-u6) + (c-call VOID "do_int" pc Dsp-10-u6) + ()) + +(dni into16 "into" ((machine 16)) + ("into") + (+ (f-0-4 #xF) (f-4-4 6)) + (nop) + ()) + +(dni int32 "int Dsp-8-u6" ((machine 32)) + ("int #${Dsp-8-u6}") + (+ (f-0-4 #xB) (f-4-4 #xE) Dsp-8-u6 (f-14-2 0)) + (c-call VOID "do_int" pc Dsp-8-u6) + ()) + +(dni into32 "into" ((machine 32)) + ("into") + (+ (f-0-4 #xB) (f-4-4 #xF)) + (nop) + ()) + +;------------------------------------------------------------- +; index (m32c) +;------------------------------------------------------------- + +; TODO add support to insns allowing index +(define-pmacro (indexb-sem mode d) (set SrcIndex d) (set DstIndex d)) +(define-pmacro (indexbd-sem mode d) (set SrcIndex (const 0)) (set DstIndex d)) +(define-pmacro (indexbs-sem mode d) (set SrcIndex d) (set DstIndex (const 0))) +(define-pmacro (indexw-sem mode d) + (set SrcIndex (sll d (const 2))) (set DstIndex (sll d (const 2)))) +(define-pmacro (indexwd-sem mode d) + (set SrcIndex (const 0)) (set DstIndex (sll d (const 2)))) +(define-pmacro (indexws-sem mode d) + (set SrcIndex (sll d (const 2))) (set DstIndex (const 0))) +(define-pmacro (indexl-sem mode d) + (set SrcIndex d) (set DstIndex (sll d (const 2)))) +(define-pmacro (indexld-sem mode d) + (set SrcIndex (const 0)) (set DstIndex (sll d (const 2)))) +(define-pmacro (indexls-sem mode d) + (set SrcIndex (sll d (const 2))) (set DstIndex (const 0))) + +; Note that "wbit" not where the size bit goes here, hence, it's +; always 0 in these calls but op2 differs instead. + +; indexb src (index byte) +(unary32-defn QI .b 0 indexb #x8 0 #x3 indexb-sem) +(unary32-defn HI .w 0 indexb #x8 1 #x3 indexb-sem) +; indexbd src (index byte dest) +(unary32-defn QI .b 0 indexbd #xA 0 3 indexbd-sem) +(unary32-defn HI .w 0 indexbd #xA 1 3 indexbd-sem) +; indexbs src (index byte src) +(unary32-defn QI .b 0 indexbs #xC 0 3 indexbs-sem) +(unary32-defn HI .w 0 indexbs #xC 1 3 indexbs-sem) +; indexl src (index long) +(unary32-defn QI .b 0 indexl 9 2 3 indexl-sem) +(unary32-defn HI .w 0 indexl 9 3 3 indexl-sem) +; indexld src (index long dest) +(unary32-defn QI .b 0 indexld #xB 2 3 indexld-sem) +(unary32-defn HI .w 0 indexld #xB 3 3 indexld-sem) +; indexls src (index long src) +(unary32-defn QI .b 0 indexls 9 0 3 indexls-sem) +(unary32-defn HI .w 0 indexls 9 1 3 indexls-sem) +; indexw src (index word) +(unary32-defn QI .b 0 indexw 8 2 3 indexw-sem) +(unary32-defn HI .w 0 indexw 8 3 3 indexw-sem) +; indexwd src (index word dest) +(unary32-defn QI .b 0 indexwd #xA 2 3 indexwd-sem) +(unary32-defn HI .w 0 indexwd #xA 3 3 indexwd-sem) +; indexws (index word src) +(unary32-defn QI .b 0 indexws #xC 2 3 indexws-sem) +(unary32-defn HI .w 0 indexws #xC 3 3 indexws-sem) + +;------------------------------------------------------------- +; jcc - jump on condition +;------------------------------------------------------------- + +(define-pmacro (jcnd32-sem cnd label) + (sequence () + (case DFLT cnd + ((#x00) (if (not cbit) (set pc label))) ;ltu nc + ((#x01) (if (not (and cbit (not zbit))) (set pc label))) ;leu + ((#x02) (if (not zbit) (set pc label))) ;ne nz + ((#x03) (if (not sbit) (set pc label))) ;pz + ((#x04) (if (not obit) (set pc label))) ;no + ((#x05) (if (not (or zbit (xor sbit obit))) (set pc label))) ;gt + ((#x06) (if (not (xor sbit obit)) (set pc label))) ;ge + ((#x08) (if (trunc BI cbit) (set pc label))) ;geu c + ((#x09) (if (and cbit (not zbit)) (set pc label))) ;gtu + ((#x0a) (if (trunc BI zbit) (set pc label))) ;eq z + ((#x0b) (if (trunc BI sbit) (set pc label))) ;n + ((#x0c) (if (trunc BI obit) (set pc label))) ;o + ((#x0d) (if (or zbit (xor sbit obit)) (set pc label))) ;le + ((#x0e) (if (xor sbit obit) (set pc label))) ;lt + ) + ) + ) + +(define-pmacro (jcnd16-sem cnd label) + (sequence () + (case DFLT cnd + ((#x00) (if (trunc BI cbit) (set pc label))) ;geu c + ((#x01) (if (and cbit (not zbit)) (set pc label))) ;gtu + ((#x02) (if (trunc BI zbit) (set pc label))) ;eq z + ((#x03) (if (trunc BI sbit) (set pc label))) ;n + ((#x04) (if (not cbit) (set pc label))) ;ltu nc + ((#x05) (if (not (and cbit (not zbit))) (set pc label))) ;leu + ((#x06) (if (not zbit) (set pc label))) ;ne nz + ((#x07) (if (not sbit) (set pc label))) ;pz + ((#x08) (if (or zbit (xor sbit obit)) (set pc label))) ;le + ((#x09) (if (trunc BI obit) (set pc label))) ;o + ((#x0a) (if (not (xor sbit obit)) (set pc label))) ;ge + ((#x0c) (if (not (or zbit (xor sbit obit))) (set pc label))) ;gt + ((#x0d) (if (not obit) (set pc label))) ;no + ((#x0e) (if (xor sbit obit) (set pc label))) ;lt + ) + ) + ) + +(dni jcnd16-5 + "jCnd label" + (RL_JUMP RELAXABLE (machine 16)) + "j$cond16j5 ${Lab-8-8}" + (+ (f-0-4 #x6) (f-4-1 1) cond16j5 Lab-8-8) + (jcnd16-sem cond16j5 Lab-8-8) + () +) + +(dni jcnd16 + "jCnd label" + (RL_JUMP RELAXABLE (machine 16)) + "j$cond16j ${Lab-16-8}" + (+ (f-0-4 #x7) (f-4-4 #xD) (f-8-4 #xC) cond16j Lab-16-8) + (jcnd16-sem cond16j Lab-16-8) + () +) + +(dni jcnd32 + "jCnd label" + (RL_JUMP RELAXABLE (machine 32)) + "j$cond32j ${Lab-8-8}" + (+ (f-0-1 1) (f-4-3 5) cond32j Lab-8-8) + (jcnd32-sem cond32j Lab-8-8) + () +) + +;------------------------------------------------------------- +; jmp - jump +;------------------------------------------------------------- + +; jmp.s label3 (m16 #1) +(dni jmp16.s "jmp.s Lab-5-3" (RL_JUMP RELAXABLE (machine 16)) + ("jmp.s ${Lab-5-3}") + (+ (f-0-4 6) (f-4-1 0) Lab-5-3) + (sequence () (set pc Lab-5-3)) + ()) +; jmp.b label8 (m16 #2) +(dni jmp16.b "jmp.b Lab-8-8" (RL_JUMP RELAXABLE (machine 16)) + ("jmp.b ${Lab-8-8}") + (+ (f-0-4 #xF) (f-4-4 #xE) Lab-8-8) + (sequence () (set pc Lab-8-8)) + ()) +; jmp.w label16 (m16 #3) +(dni jmp16.w "jmp.w Lab-8-16" (RL_JUMP RELAXABLE (machine 16)) + ("jmp.w ${Lab-8-16}") + (+ (f-0-4 #xF) (f-4-4 4) Lab-8-16) + (sequence () (set pc Lab-8-16)) + ()) +; jmp.a label24 (m16 #4) +(dni jmp16.a "jmp.a Lab-8-24" (RL_JUMP RELAXABLE (machine 16)) + ("jmp.a ${Lab-8-24}") + (+ (f-0-4 #xF) (f-4-4 #xC) Lab-8-24) + (sequence () (set pc Lab-8-24)) + ()) + +(define-pmacro (jmp16-sem mode dst) + (set pc (and dst #xfffff)) +) +(define-pmacro (jmp32-sem mode dst) + (set pc dst) +) +; jmpi.w dst (m16 #1 m32 #2) +(unary-insn-defn 16 16 HI .w jmpi (+ (f-0-4 7) (f-4-4 #xD) (f-8-4 2) dst16-16-HI) jmp16-sem) +(unary-insn-defn 32 16-Unprefixed HI .w jmpi (+ (f-0-4 #xC) (f-7-1 1) dst32-16-Unprefixed-HI (f-10-2 #x0) (f-12-4 #xF)) jmp32-sem) +; jmpi.a dst (m16 #2 m32 #2) +(unary-insn-defn 16 16 SI .a jmpi (+ (f-0-4 7) (f-4-4 #xD) (f-8-4 0) dst16-16-SI) jmp16-sem) +(unary-insn-defn 32 16-Unprefixed SI .a jmpi (+ (f-0-4 #x8) (f-7-1 0) dst32-16-Unprefixed-SI (f-10-2 #x0) (f-12-4 1)) jmp32-sem) +; jmps imm8 (m16 #1) +(dni jmps16 "jmps Imm-8-QI" ((machine 16)) + ("jmps #${Imm-8-QI}") + (+ (f-0-4 #xE) (f-4-4 #xE) Imm-8-QI) + (sequence () (set pc Imm-8-QI)) + ()) +; jmp.s label3 (m32 #1) +(dni jmp32.s + "jmp.s label" + (RL_JUMP RELAXABLE (machine 32)) + "jmp.s ${Lab32-jmp-s}" + (+ (f-0-2 1) (f-4-3 5) Lab32-jmp-s) + (set pc Lab32-jmp-s) + () +) +; jmp.b label8 (m32 #2) +(dni jmp32.b "jmp.b Lab-8-8" (RL_JUMP RELAXABLE (machine 32)) + ("jmp.b ${Lab-8-8}") + (+ (f-0-4 #xB) (f-4-4 #xB) Lab-8-8) + (set pc Lab-8-8) + ()) +; jmp.w label16 (m32 #3) +(dni jmp32.w "jmp.w Lab-8-16" (RL_JUMP RELAXABLE (machine 32)) + ("jmp.w ${Lab-8-16}") + (+ (f-0-4 #xC) (f-4-4 #xE) Lab-8-16) + (set pc Lab-8-16) + ()) +; jmp.a label24 (m32 #4) +(dni jmp32.a "jmp.a Lab-8-24" (RL_JUMP RELAXABLE (machine 32)) + ("jmp.a ${Lab-8-24}") + (+ (f-0-4 #xC) (f-4-4 #xC) Lab-8-24) + (set pc Lab-8-24) + ()) +; jmp.s imm8 (m32 #1) +(dni jmps32 "jmps Imm-8-QI" (RL_JUMP (machine 32)) + ("jmps #${Imm-8-QI}") + (+ (f-0-4 #xD) (f-4-4 #xC) Imm-8-QI) + (set pc Imm-8-QI) + ()) + +;------------------------------------------------------------- +; jsr jump subroutine +;------------------------------------------------------------- + +(define-pmacro (jsr16-sem length dst) + (sequence ((SI tpc)) + (set tpc (add pc length)) + (set (reg h-sp) (sub (reg h-sp) 2)) + (set (mem16 HI (reg h-sp)) (srl (and tpc #xffff00) 8)) + (set (reg h-sp) (sub (reg h-sp) 1)) + (set (mem16 QI (reg h-sp)) (and tpc #xff)) + (set pc dst) + ) +) +(define-pmacro (jsr32-sem length dst) + (sequence ((SI tpc)) + (set tpc (add pc length)) + (set (reg h-sp) (sub (reg h-sp) 2)) + (set (mem32 HI (reg h-sp)) (srl (and tpc #xffff0000) 16)) + (set (reg h-sp) (sub (reg h-sp) 2)) + (set (mem32 HI (reg h-sp)) (and tpc #xffff)) + (set pc dst) + ) +) + +; jsr.w label16 (m16 #1) +(dni jsr16.w "jsr.w Lab-8-16" (RL_JUMP RELAXABLE (machine 16)) + ("jsr.w ${Lab-8-16}") + (+ (f-0-4 #xF) (f-4-4 5) Lab-8-16) + (jsr16-sem 3 Lab-8-16) + ()) +; jsr.a label24 (m16 #2) +(dni jsr16.a "jsr.a Lab-8-24" (RL_JUMP RELAXABLE (machine 16)) + ("jsr.a ${Lab-8-24}") + (+ (f-0-4 #xF) (f-4-4 #xD) Lab-8-24) + (jsr16-sem 4 Lab-8-24) + ()) +(define-pmacro (jsri-defn mode op16 op16-1 op16-2 op16-3 op16-sem + op32 op32-1 op32-2 op32-3 op32-4 op32-sem len) + (begin + (dni (.sym jsri16 mode - op16) + (.str "jsri." mode " " op16) + (RL_1ADDR (machine 16)) + (.str "jsri." mode " ${" op16 "}") + (+ op16-1 op16-2 op16-3 op16) + (op16-sem len op16) + ()) + (dni (.sym jsri32 mode - op32) + (.str "jsri." mode " " op32) + (RL_1ADDR (machine 32)) + (.str "jsri." mode " ${" op32 "}") + (+ op32-1 op32-2 op32-3 op32-4 op32) + (op32-sem len op32) + ()) + ) + ) +; jsri.w dst (m16 #1 m32 #1)) +(jsri-defn w dst16-16-20ar-HI (f-0-4 #x7) (f-4-4 #xD) (f-8-4 #x3) jsr16-sem + dst32-16-24-Unprefixed-HI (f-0-4 #xC) (f-7-1 1) (f-10-2 #x1) (f-12-4 #xF) jsr32-sem 4) +(jsri-defn w dst16-16-16sa-HI (f-0-4 #x7) (f-4-4 #xD) (f-8-4 #x3) jsr16-sem + dst32-16-16sa-Unprefixed-HI (f-0-4 #xC) (f-7-1 1) (f-10-2 #x1) (f-12-4 #xF) jsr32-sem 4) +(jsri-defn w dst16-16-8-HI (f-0-4 #x7) (f-4-4 #xD) (f-8-4 #x3) jsr16-sem + dst32-16-8-Unprefixed-HI (f-0-4 #xC) (f-7-1 1) (f-10-2 #x1) (f-12-4 #xF) jsr32-sem 3) +(jsri-defn w dst16-basic-HI (f-0-4 #x7) (f-4-4 #xD) (f-8-4 #x3) jsr16-sem + dst32-basic-Unprefixed-HI (f-0-4 #xC) (f-7-1 1) (f-10-2 #x1) (f-12-4 #xF) jsr32-sem 2) + +; jsri.a (m16 #2 m32 #2) +(jsri-defn a dst16-16-20ar-SI (f-0-4 #x7) (f-4-4 #xD) (f-8-4 #x1) jsr16-sem + dst32-16-24-Unprefixed-SI (f-0-4 #x9) (f-7-1 0) (f-10-2 #x0) (f-12-4 #x1) jsr32-sem 4) +(jsri-defn a dst16-16-8-SI (f-0-4 #x7) (f-4-4 #xD) (f-8-4 #x1) jsr16-sem + dst32-16-8-Unprefixed-SI (f-0-4 #x9) (f-7-1 0) (f-10-2 #x0) (f-12-4 #x1) jsr32-sem 3) +(jsri-defn a dst16-16-16sa-SI (f-0-4 #x7) (f-4-4 #xD) (f-8-4 #x1) jsr16-sem + dst32-16-16sa-Unprefixed-SI (f-0-4 #x9) (f-7-1 0) (f-10-2 #x0) (f-12-4 #x1) jsr32-sem 4) +(jsri-defn a dst16-basic-SI (f-0-4 #x7) (f-4-4 #xD) (f-8-4 #x1) jsr16-sem + dst32-basic-Unprefixed-SI (f-0-4 #x9) (f-7-1 0) (f-10-2 #x0) (f-12-4 #x1) jsr32-sem 2) + +(dni jsri32.a "jsr.w dst32-16-24-Unprefixed-HI" (RL_1ADDR (machine 32)) + ("jsri.a ${dst32-16-24-Unprefixed-SI}") + (+ (f-0-4 #x9) (f-7-1 0) dst32-16-24-Unprefixed-SI (f-10-2 #x0) (f-12-4 #x1)) + (jsr32-sem 6 dst32-16-24-Unprefixed-SI) + ()) +; jsr.w label16 (m32 #1) +(dni jsr32.w "jsr.w label" (RL_JUMP RELAXABLE (machine 32)) + ("jsr.w ${Lab-8-16}") + (+ (f-0-4 #xC) (f-4-4 #xF) Lab-8-16) + (jsr32-sem 3 Lab-8-16) + ()) +; jsr.a label16 (m32 #2) +(dni jsr32.a "jsr.a label" (RL_JUMP (machine 32)) + ("jsr.a ${Lab-8-24}") + (+ (f-0-4 #xC) (f-4-4 #xD) Lab-8-24) + (jsr32-sem 4 Lab-8-24) + ()) +; jsrs imm8 (m16 #1) +(dni jsrs16 "jsrs Imm-8-QI" ((machine 16)) + ("jsrs #${Imm-8-QI}") + (+ (f-0-4 #xE) (f-4-4 #xF) Imm-8-QI) + (jsr16-sem 2 Imm-8-QI) + ()) +; jsrs imm8 (m32 #1) +(dni jsrs "jsrs #Imm-8-QI" ((machine 32)) + ("jsrs #${Imm-8-QI}") + (+ (f-0-4 #xD) (f-4-4 #xD) Imm-8-QI) + (jsr32-sem 2 Imm-8-QI) + ()) + +;------------------------------------------------------------- +; ldc - load control register +; stc - store control register +;------------------------------------------------------------- + +(define-pmacro (ldc32-cr1-sem src dst) + (sequence () + (case DFLT dst + ((#x0) (set (reg h-dct0) src)) + ((#x1) (set (reg h-dct1) src)) + ((#x2) (sequence ((HI tflag)) + (set tflag src) + (if (and tflag #x1) (set cbit 1)) + (if (and tflag #x2) (set dbit 1)) + (if (and tflag #x4) (set zbit 1)) + (if (and tflag #x8) (set sbit 1)) + (if (and tflag #x10) (set bbit 1)) + (if (and tflag #x20) (set obit 1)) + (if (and tflag #x40) (set ibit 1)) + (if (and tflag #x80) (set ubit 1)))) + ((#x3) (set (reg h-svf) src)) + ((#x4) (set (reg h-drc0) src)) + ((#x5) (set (reg h-drc1) src)) + ((#x6) (set (reg h-dmd0) src)) + ((#x7) (set (reg h-dmd1) src)) + ) + ) +) +(define-pmacro (ldc32-cr2-sem src dst) + (sequence () + (case DFLT dst + ((#x0) (set (reg h-intb) src)) + ((#x1) (set (reg h-sp) src)) + ((#x2) (set (reg h-sb) src)) + ((#x3) (set (reg h-fb) src)) + ((#x4) (set (reg h-svp) src)) + ((#x5) (set (reg h-vct) src)) + ((#x7) (set (reg h-isp) src)) + ) + ) +) +(define-pmacro (ldc32-cr3-sem src dst) + (sequence () + (case DFLT dst + ((#x2) (set (reg h-dma0) src)) + ((#x3) (set (reg h-dma1) src)) + ((#x4) (set (reg h-dra0) src)) + ((#x5) (set (reg h-dra1) src)) + ((#x6) (set (reg h-dsa0) src)) + ((#x7) (set (reg h-dsa1) src)) + ) + ) +) +(define-pmacro (ldc16-sem src dst) + (sequence () + (case DFLT dst + ((#x1) (set (reg h-intb) src)) + ((#x2) (set (reg h-intb) (or (reg h-intb) (sll src (const 16))))) + ((#x3) (sequence ((HI tflag)) + (set tflag src) + (if (and tflag #x1) (set cbit 1)) + (if (and tflag #x2) (set dbit 1)) + (if (and tflag #x4) (set zbit 1)) + (if (and tflag #x8) (set sbit 1)) + (if (and tflag #x10) (set bbit 1)) + (if (and tflag #x20) (set obit 1)) + (if (and tflag #x40) (set ibit 1)) + (if (and tflag #x80) (set ubit 1)))) + ((#x4) (set (reg h-isp) src)) + ((#x5) (set (reg h-sp) src)) + ((#x6) (set (reg h-sb) src)) + ((#x7) (set (reg h-fb) src)) + ) + ) +) + +(define-pmacro (stc32-cr1-sem src dst) + (sequence () + (case DFLT src + ((#x0) (set dst (reg h-dct0))) + ((#x1) (set dst (reg h-dct1))) + ((#x2) (sequence ((HI tflag)) + (set tflag 0) + (if (eq cbit 1) (set tflag (or tflag #x1))) + (if (eq dbit 1) (set tflag (or tflag #x2))) + (if (eq zbit 1) (set tflag (or tflag #x4))) + (if (eq sbit 1) (set tflag (or tflag #x8))) + (if (eq bbit 1) (set tflag (or tflag #x10))) + (if (eq obit 1) (set tflag (or tflag #x20))) + (if (eq ibit 1) (set tflag (or tflag #x40))) + (if (eq ubit 1) (set tflag (or tflag #x80))) + (set dst tflag))) + ((#x3) (set dst (reg h-svf))) + ((#x4) (set dst (reg h-drc0))) + ((#x5) (set dst (reg h-drc1))) + ((#x6) (set dst (reg h-dmd0))) + ((#x7) (set dst (reg h-dmd1))) + ) + ) +) +(define-pmacro (stc32-cr2-sem src dst) + (sequence () + (case DFLT src + ((#x0) (set dst (reg h-intb))) + ((#x1) (set dst (reg h-sp))) + ((#x2) (set dst (reg h-sb))) + ((#x3) (set dst (reg h-fb))) + ((#x4) (set dst (reg h-svp))) + ((#x5) (set dst (reg h-vct))) + ((#x7) (set dst (reg h-isp))) + ) + ) +) +(define-pmacro (stc32-cr3-sem src dst) + (sequence () + (case DFLT src + ((#x2) (set dst (reg h-dma0))) + ((#x3) (set dst (reg h-dma1))) + ((#x4) (set dst (reg h-dra0))) + ((#x5) (set dst (reg h-dra1))) + ((#x6) (set dst (reg h-dsa0))) + ((#x7) (set dst (reg h-dsa1))) + ) + ) +) +(define-pmacro (stc16-sem src dst) + (sequence () + (case DFLT src + ((#x1) (set dst (and (reg h-intb) (const #xffff)))) + ((#x2) (set dst (srl (reg h-intb) (const 16)))) + ((#x3) (sequence ((HI tflag)) + (set tflag 0) + (if (eq cbit 1) (set tflag (or tflag #x1))) + (if (eq dbit 1) (set tflag (or tflag #x2))) + (if (eq zbit 1) (set tflag (or tflag #x4))) + (if (eq sbit 1) (set tflag (or tflag #x8))) + (if (eq bbit 1) (set tflag (or tflag #x10))) + (if (eq obit 1) (set tflag (or tflag #x20))) + (if (eq ibit 1) (set tflag (or tflag #x40))) + (if (eq ubit 1) (set tflag (or tflag #x80))) + (set dst tflag))) + ((#x4) (set dst (reg h-isp))) + ((#x5) (set dst (reg h-sp))) + ((#x6) (set dst (reg h-sb))) + ((#x7) (set dst (reg h-fb))) + ) + ) +) + +(dni ldc16.imm16 "ldc #imm,dst" ((machine 16)) + ("ldc #${Imm-16-HI},${cr16}") + (+ (f-0-4 #xE) (f-4-4 #xB) (f-8-1 0) (f-12-4 0) cr16 Imm-16-HI) + (ldc16-sem Imm-16-HI cr16) + ()) + +(dni ldc16.dst "ldc src,dest" ((machine 16)) + ("ldc ${dst16-16-HI},${cr16}") + (+ (f-0-4 7) (f-4-4 #xA) (f-8-1 1) cr16 dst16-16-HI) + (ldc16-sem dst16-16-HI cr16) + ()) +; ldc src,dest (m32c #4) +(dni ldc32.src-cr1 "ldc src,dst" ((machine 32)) + ("ldc ${dst32-24-Prefixed-HI},${cr1-Prefixed-32}") + (+ (f-0-4 0) (f-4-4 1) (f-8-4 #xD) dst32-24-Prefixed-HI (f-15-1 1) (f-18-2 0) (f-20-1 1) cr1-Prefixed-32) + (ldc32-cr1-sem dst32-24-Prefixed-HI cr1-Prefixed-32) + ()) +; ldc src,dest (m32c #5) +(dni ldc32.src-cr2 "ldc src,dest" ((machine 32)) + ("ldc ${dst32-16-Unprefixed-SI},${cr2-32}") + (+ (f-0-4 #xD) dst32-16-Unprefixed-SI (f-7-1 1) (f-10-2 0) (f-12-1 0) cr2-32) + (ldc32-cr2-sem dst32-16-Unprefixed-SI cr2-32) + ()) +; ldc src,dest (m32c #6) +(dni ldc32.src-cr3 "ldc src,dst" ((machine 32)) + ("ldc ${dst32-24-Prefixed-SI},${cr3-Prefixed-32}") + (+ (f-0-4 0) (f-4-4 1) (f-8-4 #xD) dst32-24-Prefixed-SI (f-15-1 1) (f-18-2 0) (f-20-1 0) cr3-Prefixed-32) + (ldc32-cr3-sem dst32-24-Prefixed-SI cr3-Prefixed-32) + ()) +; ldc src,dest (m32c #1) +(dni ldc32.imm16-cr1 "ldc #imm,dst" ((machine 32)) + ("ldc #${Imm-16-HI},${cr1-Unprefixed-32}") + (+ (f-0-4 #xD) (f-4-4 5) (f-8-4 #xA) (f-12-1 1) cr1-Unprefixed-32 Imm-16-HI) + (ldc32-cr1-sem Imm-16-HI cr1-Unprefixed-32) + ()) +; ldc src,dest (m32c #2) +(dni ldc32.imm16-cr2 "ldc #imm,dst" ((machine 32)) + ("ldc #${Dsp-16-u24},${cr2-32}") + (+ (f-0-4 #xD) (f-4-4 5) (f-8-4 2) (f-12-1 1) cr2-32 Dsp-16-u24) + (ldc32-cr2-sem Dsp-16-u24 cr2-32) + ()) +; ldc src,dest (m32c #3) +(dni ldc32.imm16-cr3 "ldc #imm,dst" ((machine 32)) + ("ldc #${Dsp-16-u24},${cr3-Unprefixed-32}") + (+ (f-0-4 #xD) (f-4-4 5) (f-8-4 6) (f-12-1 1) cr3-Unprefixed-32 Dsp-16-u24) + (ldc32-cr3-sem Dsp-16-u24 cr3-Unprefixed-32) + ()) + +(dni stc16.src "stc src,dest" ((machine 16)) + ("stc ${cr16},${dst16-16-HI}") + (+ (f-0-4 7) (f-4-4 #xB) (f-8-1 1) cr16 dst16-16-HI) + (stc16-sem cr16 dst16-16-HI ) + ()) + +(dni stc16.pc "stc pc,dest" ((machine 16)) + ("stc pc,${dst16-16-HI}") + (+ (f-0-4 7) (f-4-4 #xC) (f-8-4 #xC) dst16-16-HI) + (sequence () (set dst16-16-HI (reg h-pc))) + ()) + +(dni stc32.src-cr1 "stc src,dst" ((machine 32)) + ("stc ${cr1-Prefixed-32},${dst32-24-Prefixed-HI}") + (+ (f-0-4 0) (f-4-4 1) (f-8-4 #xD) dst32-24-Prefixed-HI (f-15-1 1) (f-18-2 1) (f-20-1 1) cr1-Prefixed-32) + (stc32-cr1-sem cr1-Prefixed-32 dst32-24-Prefixed-HI ) + ()) + +(dni stc32.src-cr2 "stc src,dest" ((machine 32)) + ("stc ${cr2-32},${dst32-16-Unprefixed-SI}") + (+ (f-0-4 #xD) dst32-16-Unprefixed-SI (f-7-1 1) (f-10-2 0) (f-12-1 2) cr2-32) + (stc32-cr2-sem cr2-32 dst32-16-Unprefixed-SI ) + ()) + +(dni stc32.src-cr3 "stc src,dst" ((machine 32)) + ("stc ${cr3-Prefixed-32},${dst32-24-Prefixed-SI}") + (+ (f-0-4 0) (f-4-4 1) (f-8-4 #xD) dst32-24-Prefixed-SI (f-15-1 1) (f-18-2 1) (f-20-1 0) cr3-Prefixed-32) + (stc32-cr3-sem cr3-Prefixed-32 dst32-24-Prefixed-SI ) + ()) + +;------------------------------------------------------------- +; ldctx - load context +; stctx - store context +;------------------------------------------------------------- + +; ??? semantics +(dni ldctx16 "ldctx abs16,abs24" ((machine 16)) + ("ldctx ${Dsp-16-u16},${Dsp-32-u24}") + (+ (f-0-4 #x7) (f-4-4 #xC) (f-8-4 #xF) (f-12-4 #x0) Dsp-16-u16 Dsp-32-u24) + (nop) + ()) +(dni ldctx32 "ldctx abs16,abs24" ((machine 32)) + ("ldctx ${Dsp-16-u16},${Dsp-32-u24}") + (+ (f-0-4 #xB) (f-4-4 #x6) (f-8-4 #xC) (f-12-4 #x3) Dsp-16-u16 Dsp-32-u24) + (nop) + ()) +(dni stctx16 "stctx abs16,abs24" ((machine 16)) + ("stctx ${Dsp-16-u16},${Dsp-32-u24}") + (+ (f-0-4 #x7) (f-4-4 #xD) (f-8-4 #xF) (f-12-4 #x0) Dsp-16-u16 Dsp-32-u24) + (nop) + ()) +(dni stctx32 "stctx abs16,abs24" ((machine 32)) + ("stctx ${Dsp-16-u16},${Dsp-32-u24}") + (+ (f-0-4 #xB) (f-4-4 #x6) (f-8-4 #xD) (f-12-4 #x3) Dsp-16-u16 Dsp-32-u24) + (nop) + ()) + +;------------------------------------------------------------- +; lde - load from extra far data area (m16) +; ste - store to extra far data area (m16) +;------------------------------------------------------------- + +(lde-dst QI .b 0) +(lde-dst HI .w 1) + +(ste-dst QI .b 0) +(ste-dst HI .w 1) + +;------------------------------------------------------------- +; ldipl - load interrupt permission level +;------------------------------------------------------------- + +; ??? semantics +; ldintb <==> ldc #imm,intbh ; ldc #imm,intbl + +(dni ldipl16.imm "ldipl #imm" ((machine 16)) + ("ldipl #${Imm-13-u3}") + (+ (f-0-4 #x7) (f-4-4 #xD) (f-8-4 #xA) (f-12-1 0) Imm-13-u3) + (nop) + ()) +(dni ldipl32.imm "ldipl #imm" ((machine 32)) + ("ldipl #${Imm-13-u3}") + (+ (f-0-4 #xD) (f-4-4 5) (f-8-4 #xE) (f-12-1 1) Imm-13-u3) + (nop) + ()) + + +;------------------------------------------------------------- +; max - maximum value +;------------------------------------------------------------- + +; TODO check semantics for min -1,0 +(define-pmacro (max-sem mode src dst) + (sequence () + (if (gt mode src dst) + (set mode dst src))) +) + +; max.size:G #imm,dst +(binary-arith32-imm-dst-Prefixed QI QI .b 0 max X #x8 #x3 #xF max-sem) +(binary-arith32-imm-dst-Prefixed HI HI .w 1 max X #x8 #x3 #xF max-sem) + +; max.BW:G src,dst +(binary-arith32-src-dst-Prefixed QI QI .b 0 max X #x1 #xD max-sem) +(binary-arith32-src-dst-Prefixed HI HI .w 1 max X #x1 #xD max-sem) + +;------------------------------------------------------------- +; min - minimum value +;------------------------------------------------------------- + +(define-pmacro (min-sem mode src dst) + (sequence () + (if (lt mode src dst) + (set mode dst src))) +) + +; min.size:G #imm,dst +(binary-arith32-imm-dst-Prefixed QI QI .b 0 min X #x8 #x2 #xF min-sem) +(binary-arith32-imm-dst-Prefixed HI HI .w 1 min X #x8 #x2 #xF min-sem) + +; min.BW:G src,dst +(binary-arith32-src-dst-Prefixed QI QI .b 0 min X #x1 #xC min-sem) +(binary-arith32-src-dst-Prefixed HI HI .w 1 min X #x1 #xC min-sem) + +;------------------------------------------------------------- +; mov - move +;------------------------------------------------------------- + +(define-pmacro (mov-sem mode src1 dst) + (sequence ((mode result)) + (set result src1) + (set-z-and-s result) + (set mode dst src1)) +) + +(define-pmacro (mov-dspsp-dst-sem mach mode src1 dst) + (set dst (mem-mach mach mode (add sp src1))) +) + +(define-pmacro (mov-src-dspsp-sem mach mode src dst1) + (set (mem-mach mach mode (add sp dst1)) src) +) + +(define-pmacro (mov16-imm-an-defn size mode imm regn op1 op2) + (dni (.sym mov16. size .S-imm- regn) + (.str "mov." size ":S " imm "," regn) + ((machine 16)) + (.str "mov." size "$S #${" imm "}," regn) + (+ op1 op2 imm) + (mov-sem mode imm (reg (.sym h- regn))) + ()) +) +; mov.size:G #imm,dst (m16 #1 m32 #1) +(binary-arith-imm-dst mov G (f-0-4 7) (f-4-3 2) (f-8-4 #xC) #x9 #x2 #xF mov-sem) +; mov.L:G #imm32,dst (m32 #2) +(binary-arith32-imm-dst-defn SI SI .l 0 mov G #xB #x3 #x1 mov-sem) +; mov.BW:S #imm,dst2 (m32 #4) +(binary-arith32-s-imm-dst QI .b 0 mov #x0 #x2 mov-sem) +(binary-arith32-s-imm-dst HI .w 1 mov #x0 #x2 mov-sem) +; mov.b:S #imm8,dst3 (m16 #3) +(binary-arith16-b-S-imm8-dst3 mov ".b" (f-0-4 #xC) (f-4-1 0) mov-sem) +; mov.b:S #imm8,aN (m16 #4) +(mov16-imm-an-defn b QI Imm-8-QI a0 (f-0-4 #xE) (f-4-4 2)) +(mov16-imm-an-defn b QI Imm-8-QI a1 (f-0-4 #xE) (f-4-4 #xA)) +(mov16-imm-an-defn w HI Imm-8-HI a0 (f-0-4 #xA) (f-4-4 2)) +(mov16-imm-an-defn w HI Imm-8-HI a1 (f-0-4 #xA) (f-4-4 #xA)) +; mov.WL:S #imm,A0/A1 (m32 #5) +(define-pmacro (mov32-wl-s-defn mode sz op1 imm regn op2) + (dni (.sym mov32- sz - regn) + (.str "mov." sz ":s" imm "," regn) + ((machine 32)) + (.str "mov." sz "$S #${" imm "}," regn) + (+ (f-0-4 op1) (f-4-4 op2) imm) + (mov-sem mode imm (reg (.sym h- regn))) + ()) +) +(mov32-wl-s-defn HI w #x9 Imm-8-HI a0 #xC) +(mov32-wl-s-defn HI w #x9 Imm-8-HI a1 #xD) +(mov32-wl-s-defn SI l #xB Dsp-8-s24 a0 #xC) +(mov32-wl-s-defn SI l #xB Dsp-8-s24 a1 #xD) + +; mov.size:Q #imm4,dst (m16 #2 m32 #3) +(binary-arith16-imm4-dst-defn QI .b 0 0 mov (f-0-4 #xD) (f-4-3 4) mov-sem) +(binary-arith16-imm4-dst-defn HI .w 0 1 mov (f-0-4 #xD) (f-4-3 4) mov-sem) +(binary-arith32-imm4-dst-defn QI .b 1 0 mov #x7 #x2 mov-sem) +(binary-arith32-imm4-dst-defn HI .w 1 1 mov #x7 #x2 mov-sem) + +; mov.BW:Z #0,dst (m16 #5 m32 #6) +(dni mov16.b-Z-imm8-dst3 + "mov.b:Z #0,Dst16-3-S-8" + ((machine 16)) + "mov.b$Z #0,${Dst16-3-S-8}" + (+ (f-0-4 #xB) (f-4-1 #x0) Dst16-3-S-8) + (mov-sem QI (const 0) Dst16-3-S-8) + ()) +; (binary-arith16-b-Z-imm8-dst3 mov ".b" (f-0-4 #xB) (f-4-1 0) mov-sem) +(binary-arith32-z-imm-dst QI .b 0 mov #x0 #x1 mov-sem) +(binary-arith32-z-imm-dst HI .w 1 mov #x0 #x1 mov-sem) +; mov.BW:G src,dst (m16 #6 m32 #7) +(binary-arith-src-dst mov G (f-0-4 #x7) (f-4-3 1) #x1 #xB mov-sem) +; mov.B:S src2,a0/a1 (m16 #7) +(dni (.sym mov 16 .b.S-An) + (.str mov ".b:S src2,a[01]") + ((machine 16)) + (.str mov ".b$S ${src16-2-S},${Dst16AnQI-S}") + (+ (f-0-4 #x3) (f-4-1 0) Dst16AnQI-S src16-2-S) + (mov-sem QI src16-2-S Dst16AnQI-S) + ()) +(define-pmacro (mov16-b-s-an-defn op1 op2 op2c) + (dni (.sym mov16.b.S- op1 - op2) + (.str mov ".b:S " op1 "," op2) + ((machine 16)) + (.str mov ".b$S " op1 "," op2) + (+ (f-0-4 #x3) op2c) + (mov-sem QI (reg (.sym h- op1)) (reg (.sym h- op2))) + ()) + ) +(mov16-b-s-an-defn r0l a1 (f-4-4 #x4)) +(mov16-b-s-an-defn r0h a0 (f-4-4 #x0)) + +; mov.L:G src,dst (m32 #8) +(binary-arith32-src-dst-defn SI SI .l 1 mov G #x1 #x3 mov-sem) +; mov.B:S r0l/r0h,dst2 (m16 #8) +(dni (.sym mov 16 .b.S-Rn-An) + (.str mov ".b:S r0[lh],src2") + ((machine 16)) + (.str mov ".b$S ${Dst16RnQI-S},${src16-2-S}") + (+ (f-0-4 #x0) (f-4-1 0) Dst16RnQI-S src16-2-S) + (mov-sem QI src16-2-S Dst16RnQI-S) + ()) + +; mov.B.S src2,r0l/r0h (m16 #9) +(binary-arith16-b-S-src2 mov (f-0-4 0) (f-4-1 1) mov-sem) + +; mov.BW:S src2,r0l/r0 (m32 #9) +; mov.BW:S src2,r1l/r1 (m32 #10) +(define-pmacro (mov32-src-r sz szcode mode src dst opc1 opc2) + (begin + (dni (.sym mov32. sz - src - dst) + (.str "mov." sz "src," dst) + ((machine 32)) + (.str "mov." sz "$S ${" (.sym src - mode) "}," dst) + (+ (f-0-2 opc1) (.sym src - mode) (f-4-3 opc2) (f-7-1 szcode)) + (mov-sem mode (.sym src - mode) (reg (.sym h- dst))) + ()) + ) + ) +(mov32-src-r b 0 QI dst32-2-S-16 r0l 0 4) +(mov32-src-r w 1 HI dst32-2-S-16 r0 0 4) +(mov32-src-r b 0 QI dst32-2-S-8 r0l 0 4) +(mov32-src-r w 1 HI dst32-2-S-8 r0 0 4) +(mov32-src-r b 0 QI dst32-2-S-basic r1l 1 7) +(mov32-src-r w 1 HI dst32-2-S-basic r1 1 7) +(mov32-src-r b 0 QI dst32-2-S-16 r1l 1 7) +(mov32-src-r w 1 HI dst32-2-S-16 r1 1 7) +(mov32-src-r b 0 QI dst32-2-S-8 r1l 1 7) +(mov32-src-r w 1 HI dst32-2-S-8 r1 1 7) + +; mov.BW:S r0l/r0,dst2 (m32 #11) +(define-pmacro (mov32-r-dest sz szcode mode src dst opc1 opc2) + (begin + (dni (.sym mov32. sz - src - dst) + (.str "mov." sz "src," dst) + ((machine 32)) + (.str "mov." sz "$S " src ",${" (.sym dst - mode) "}") + (+ (f-0-2 opc1) (.sym dst - mode) (f-4-3 opc2) (f-7-1 szcode)) + (mov-sem mode (reg (.sym h- src)) (.sym dst - mode)) + ()) + ) + ) +(mov32-r-dest b 0 QI r0l dst32-2-S-16 0 0) +(mov32-r-dest w 1 HI r0 dst32-2-S-16 0 0) +(mov32-r-dest b 0 QI r0l dst32-2-S-8 0 0) +(mov32-r-dest w 1 HI r0 dst32-2-S-8 0 0) + +; mov.L:S src,A0/A1 (m32 #12) +(define-pmacro (mov32-src-a src dst dstcode opc1 opc2) + (begin + (dni (.sym mov32. sz - src - dst) + (.str "mov." sz "src," dst) + ((machine 32)) + (.str "mov.l" "$S ${" (.sym src - SI) "}," dst) + (+ (f-0-2 opc1) (.sym src - SI) (f-4-3 opc2) (f-7-1 dstcode)) + (mov-sem SI (.sym src - SI) (reg (.sym h- dst))) + ()) + ) + ) +(mov32-src-a dst32-2-S-16 a0 0 1 4) +(mov32-src-a dst32-2-S-16 a1 1 1 4) +(mov32-src-a dst32-2-S-8 a0 0 1 4) +(mov32-src-a dst32-2-S-8 a1 1 1 4) + +; mov.BW:G dsp8[sp],dst (m16 #10 m32 #13) +; mov.BW:G src,dsp8[sp] (m16 #11 m32 #14) +(mov-dspsp-dst mov (f-0-4 #x7) (f-4-3 2) (f-8-4 #xB) #xB #x0 #xF mov-dspsp-dst-sem) +(mov-src-dspsp mov (f-0-4 #x7) (f-4-3 2) (f-8-4 #x3) #xA #x0 #xF mov-src-dspsp-sem) + +;------------------------------------------------------------- +; mova - move effective address +;------------------------------------------------------------- + +(define-pmacro (mov16a-defn dst dstop dstcode) + (dni (.sym mova16. src - dst) + (.str "mova src," dst) + ((machine 16)) + (.str "mova ${dst16-16-Mova-HI}," dst) + (+ (f-0-4 #xE) (f-4-4 #xB) dst16-16-Mova-HI (f-8-4 dstcode)) + (sequence () (set HI (reg dstop) dst16-16-Mova-HI)) + ()) +) +(mov16a-defn r0 h-r0 0) +(mov16a-defn r1 h-r1 1) +(mov16a-defn r2 h-r2 2) +(mov16a-defn r3 h-r3 3) +(mov16a-defn a0 h-a0 4) +(mov16a-defn a1 h-a1 5) + +(define-pmacro (mov32a-defn dst dstop dstcode) + (dni (.sym mova32. src - dst) + (.str "mova src," dst) + ((machine 32)) + (.str "mova ${dst32-16-Unprefixed-Mova-SI}," dst) + (+ (f-0-4 #xD) dst32-16-Unprefixed-Mova-SI (f-7-1 1) (f-10-2 1) (f-12-1 1) (f-13-3 dstcode)) + (sequence () (set SI (reg dstop) dst32-16-Unprefixed-Mova-SI)) + ()) +) +(mov32a-defn r2r0 h-r2r0 0) +(mov32a-defn r3r1 h-r3r1 1) +(mov32a-defn a0 h-a0 2) +(mov32a-defn a1 h-a1 3) + +;------------------------------------------------------------- +; movDir - move nibble +;------------------------------------------------------------- + +(define-pmacro (movdir-sem nib src dst) + (sequence ((SI tmp)) + (case DFLT nib + ((0) (set dst (or (and dst #xf0) (and src #xf)))) + ((1) (set dst (or (and dst #x0f) (sll (and src #xf) 4)))) + ((2) (set dst (or (and dst #xf0) (srl (and src #xf0) 4)))) + ((3) (set dst (or (and dst #x0f) (and src #xf0)))) + ) + ) + ) +; movDir src,dst +(define-pmacro (mov16dir-1-defn nib dircode dir) + (dni (.sym mov nib 16 ".r0l-dst") + (.str "mov" nib " r0l,dst") + ((machine 16)) + (.str "mov" nib " r0l,${dst16-16-QI}") + (+ (f-0-4 7) (f-4-4 #xC) (f-8-4 dir) dst16-16-QI) + (movdir-sem dircode (reg h-r0l) dst16-16-QI) + ()) +) +(mov16dir-1-defn ll 0 8) +(mov16dir-1-defn lh 1 #xA) +(mov16dir-1-defn hl 2 9) +(mov16dir-1-defn hh 3 #xB) +(define-pmacro (mov16dir-2-defn nib dircode dir) + (dni (.sym mov nib 16 ".src-r0l") + (.str "mov" nib " src,r0l") + ((machine 16)) + (.str "mov" nib " ${dst16-16-QI},r0l") + (+ (f-0-4 7) (f-4-4 #xC) (f-8-4 dir) dst16-16-QI) + (movdir-sem dircode dst16-16-QI (reg h-r0l)) + ()) +) +(mov16dir-2-defn ll 0 0) +(mov16dir-2-defn lh 1 2) +(mov16dir-2-defn hl 2 1) +(mov16dir-2-defn hh 3 3) + +(define-pmacro (mov32dir-1-defn nib o1o0) + (dni (.sym mov nib 32 ".r0l-dst") + (.str "mov" nib " r0l,dst") + ((machine 32)) + (.str "mov" nib " r0l,${dst32-24-Prefixed-QI}") + (+ (f-0-4 #x0) (f-4-4 #x1) (f-8-4 #xB) dst32-24-Prefixed-QI (f-15-1 0) (f-18-2 o1o0) (f-20-4 #xE)) + (movdir-sem o1o0 (reg h-r0l) dst32-24-Prefixed-QI) + ()) +) +(mov32dir-1-defn ll 0) +(mov32dir-1-defn lh 1) +(mov32dir-1-defn hl 2) +(mov32dir-1-defn hh 3) +(define-pmacro (mov32dir-2-defn nib o1o0) + (dni (.sym mov nib 32 ".src-r0l") + (.str "mov" nib " src,r0l") + ((machine 32)) + (.str "mov" nib " ${dst32-24-Prefixed-QI},r0l") + (+ (f-0-4 #x0) (f-4-4 #x1) (f-8-4 #xA) dst32-24-Prefixed-QI (f-15-1 0) (f-18-2 o1o0) (f-20-4 #xE)) + (movdir-sem o1o0 dst32-24-Prefixed-QI (reg h-r0l)) + ()) +) +(mov32dir-2-defn ll 0) +(mov32dir-2-defn lh 1) +(mov32dir-2-defn hl 2) +(mov32dir-2-defn hh 3) + +;------------------------------------------------------------- +; movx - move extend sign (m32) +;------------------------------------------------------------- + +(define-pmacro (movx-sem mode src dst) + (sequence ((SI source) (SI result)) + (set SI result src) + (set-z-and-s result) + (set dst result)) +) + +; movx #imm,dst +(binary-arith32-imm-dst-defn QI SI "" 0 movx X #xB #x1 #x1 movx-sem) + +;------------------------------------------------------------- +; mul - multiply +;------------------------------------------------------------- + +(define-pmacro (mul-sem mode src1 dst) + (sequence ((mode result)) + (set obit (add-oflag mode src1 dst 0)) + (set result (mul mode src1 dst)) + (set dst result)) +) + +; mul.BW #imm,dst +(binary-arith-imm-dst mul G (f-0-4 7) (f-4-3 6) (f-8-4 5) #x8 #x1 #xF mul-sem) +; mul.BW src,dst +(binary-arith-src-dst mul G (f-0-4 #x7) (f-4-3 4) #x1 #xC mul-sem) + +(dni mul_l "mul.l src,r2r0" ((machine 32)) + ("mul.l ${dst32-24-Prefixed-SI},r2r0") + (+ (f-0-4 #x0) (f-4-4 #x1) (f-8-4 #x8) (f-15-1 #x1) (f-18-2 #x1) (f-20-4 #xf) + dst32-24-Prefixed-SI) + () ()) + +(dni mulu_l "mulu.l src,r2r0" ((machine 32)) + ("mulu.l ${dst32-24-Prefixed-SI},r2r0") + (+ (f-0-4 #x0) (f-4-4 #x1) (f-8-4 #x8) (f-15-1 #x1) (f-18-2 #x0) (f-20-4 #xf) + dst32-24-Prefixed-SI) + () ()) +;------------------------------------------------------------- +; mulex - multiple extend sign (m32) +;------------------------------------------------------------- + +; mulex src,dst +; (dni mulex-absolute-indirect "mulex [src]" ((machine 32)) +; ("mulex ${dst32-24-absolute-indirect-HI}") +; (+ (f-0-4 0) (f-4-4 9) (f-8-4 #xC) dst32-24-absolute-indirect-HI (f-15-1 1) (f-18-2 3) (f-20-4 #xE)) +; (set R1R2R0 (mul DI (ext DI R2R0) (ext DI dst32-24-absolute-indirect-HI))) +; ()) +(dni mulex "mulex src" ((machine 32)) + ("mulex ${dst32-16-Unprefixed-Mulex-HI}") + (+ (f-0-4 #xC) dst32-16-Unprefixed-Mulex-HI (f-7-1 1) (f-10-2 3) (f-12-4 #xE)) + (set R1R2R0 (mul DI (ext DI R2R0) (ext DI dst32-16-Unprefixed-Mulex-HI))) + ()) +; (dni mulex-indirect "mulex [src]" ((machine 32)) +; ("mulex ${dst32-24-indirect-HI}") +; (+ (f-0-4 0) (f-4-4 9) (f-8-4 #xC) dst32-24-indirect-HI (f-15-1 1) (f-18-2 3) (f-20-4 #xE)) +; (set R1R2R0 (mul DI (ext DI R2R0) (ext DI dst32-24-indirect-HI))) +; ()) + +;------------------------------------------------------------- +; mulu - multiply unsigned +;------------------------------------------------------------- + +(define-pmacro (mulu-sem mode src1 dst) + (sequence ((mode result)) + (set obit (add-oflag mode src1 dst 0)) + (set result (mul mode src1 dst)) + (set dst result)) +) + +; mulu.BW #imm,dst +(binary-arith-imm-dst mulu G (f-0-4 7) (f-4-3 6) (f-8-4 4) #x8 #x0 #xF mulu-sem) +; mulu.BW src,dst +(binary-arith-src-dst mulu G (f-0-4 #x7) (f-4-3 0) #x1 #x4 mulu-sem) + +;------------------------------------------------------------- +; neg - twos complement +;------------------------------------------------------------- + +(define-pmacro (neg-sem mode dst) + (sequence ((mode result)) + (set result (neg mode dst)) + (set-z-and-s result) + (set dst result)) +) + +; neg.BW:G +(unary-insn neg (f-0-4 7) (f-4-3 2) (f-8-4 #x5) #xA #x2 #xF neg-sem) + +;------------------------------------------------------------- +; not - twos complement +;------------------------------------------------------------- + +(define-pmacro (not-sem mode dst) + (sequence ((mode result)) + (set result (not mode dst)) + (set-z-and-s result) + (set dst result)) +) + +; not.BW:G +(unary-insn-g not (f-0-4 7) (f-4-3 2) (f-8-4 #x7) #xA #x1 #xE not-sem) + +(dni not16.b.s + "not.b:s Dst16-3-S-8" + ((machine 16)) + "not.b:s ${Dst16-3-S-8}" + (+ (f-0-4 #xb) (f-4-1 #x1) Dst16-3-S-8) + (not-sem QI Dst16-3-S-8) + ()) + +;------------------------------------------------------------- +; nop +;------------------------------------------------------------- + +(dni nop16 + "nop" + ((machine 16)) + "nop" + (+ (f-0-4 #x0) (f-4-4 #x4)) + (nop) + ()) + +(dni nop32 + "nop" + ((machine 32)) + "nop" + (+ (f-0-4 #xD) (f-4-4 #xE)) + (nop) + ()) + +;------------------------------------------------------------- +; or - logical or +;------------------------------------------------------------- + +(define-pmacro (or-sem mode src1 dst) + (sequence ((mode result)) + (set result (or mode src1 dst)) + (set-z-and-s result) + (set dst result)) +) + +; or.BW #imm,dst (m16 #1 m32 #1) +(binary-arith-imm-dst or G (f-0-4 7) (f-4-3 3) (f-8-4 3) #x8 #x2 #xF or-sem) +; or.b:S #imm8,dst3 (m16 #2 m32 #2) +(binary-arith16-b-S-imm8-dst3 or ".b" (f-0-4 9) (f-4-1 1) or-sem) +(binary-arith32-s-imm-dst QI .b 0 or #x1 #x2 or-sem) +(binary-arith32-s-imm-dst HI .w 1 or #x1 #x2 or-sem) +; or.BW src,dst (m16 #3 m32 #3) +(binary-arith-src-dst or G (f-0-4 #x9) (f-4-3 4) #x1 #x5 or-sem) +; or.b:S src,r0[lh] (m16) +(binary-arith16-b-S-src2 or (f-0-4 1) (f-4-1 1) or-sem) + +;------------------------------------------------------------- +; pop - restore register/memory +;------------------------------------------------------------- + +; TODO future: split this into .b and .w semantics +(define-pmacro (pop-sem-mach mach mode dst) + (sequence ((mode b_or_w) (SI length)) + (set b_or_w -1) + (set b_or_w (srl b_or_w #x8)) + (if (eq b_or_w #x0) + (set length 1) ; .b + (set length 2)) ; .w + + (case DFLT length + ((1) (set dst (mem-mach mach QI (reg h-sp)))) + ((2) (set dst (mem-mach mach HI (reg h-sp))))) + (set (reg h-sp) (add (reg h-sp) length)) + ) +) + +(define-pmacro (pop-sem16 mode dest) (pop-sem-mach 16 mode dest)) +(define-pmacro (pop-sem32 mode dest) (pop-sem-mach 32 mode dest)) + +; pop.BW:G (m16 #1) +(unary-insn-mach-g 16 pop (f-0-4 7) (f-4-3 2) (f-8-4 #xD) pop-sem16 $G) +; pop.BW:G (m32 #1) +(unary-insn-mach 32 pop #xB #x2 #xF pop-sem32) + +; pop.b:S r0l/r0h +(dni pop16.b-s-rn "pop.b:S r0[lh]" ((machine 16)) + "pop.b$S ${Rn16-push-S-anyof}" + (+ (f-0-4 #x9) Rn16-push-S-anyof (f-5-3 #x2)) + (pop-sem16 QI Rn16-push-S-anyof) + ()) +; pop.w:S a0/a1 +(dni pop16.b-s-an "pop.w:S a[01]" ((machine 16)) + "pop.w$S ${An16-push-S-anyof}" + (+ (f-0-4 #xD) An16-push-S-anyof (f-5-3 #x2)) + (pop-sem16 HI An16-push-S-anyof) + ()) + +;------------------------------------------------------------- +; popc - pop control register +; pushc - push control register +;------------------------------------------------------------- + +(define-pmacro (popc32-cr1-sem mode dst) + (sequence () + (case DFLT dst + ((#x0) (set (reg h-dct0) (mem32 mode (reg h-sp)))) + ((#x1) (set (reg h-dct1) (mem32 mode (reg h-sp)))) + ((#x2) (sequence ((HI tflag)) + (set tflag (mem32 mode (reg h-sp))) + (if (and tflag #x1) (set cbit 1)) + (if (and tflag #x2) (set dbit 1)) + (if (and tflag #x4) (set zbit 1)) + (if (and tflag #x8) (set sbit 1)) + (if (and tflag #x10) (set bbit 1)) + (if (and tflag #x20) (set obit 1)) + (if (and tflag #x40) (set ibit 1)) + (if (and tflag #x80) (set ubit 1)))) + ((#x3) (set (reg h-svf) (mem32 mode (reg h-sp)))) + ((#x4) (set (reg h-drc0) (mem32 mode (reg h-sp)))) + ((#x5) (set (reg h-drc1) (mem32 mode (reg h-sp)))) + ((#x6) (set (reg h-dmd0) (mem32 mode (reg h-sp)))) + ((#x7) (set (reg h-dmd1) (mem32 mode (reg h-sp)))) + ) + (set (reg h-sp) (add (reg h-sp) 2)) + ) +) +(define-pmacro (popc32-cr2-sem mode dst) + (sequence () + (case DFLT dst + ((#x0) (set (reg h-intb) (mem32 mode (reg h-sp)))) + ((#x1) (set (reg h-sp) (mem32 mode (reg h-sp)))) + ((#x2) (set (reg h-sb) (mem32 mode (reg h-sp)))) + ((#x3) (set (reg h-fb) (mem32 mode (reg h-sp)))) + ((#x7) (set (reg h-isp) (mem32 mode (reg h-sp)))) + ) + (set (reg h-sp) (add (reg h-sp) 4)) + ) +) +(define-pmacro (popc16-sem mode dst) + (sequence () + (case DFLT dst + ((#x1) (set (reg h-intb) (or (and (reg h-intb) #x0000) + (mem16 mode (reg h-sp))))) + ((#x2) (set (reg h-intb) (or (and (reg h-intb) #xffff0000) + (mem16 mode (reg h-sp))))) + ((#x3) (sequence ((HI tflag)) + (set tflag (mem16 mode (reg h-sp))) + (if (and tflag #x1) (set cbit 1)) + (if (and tflag #x2) (set dbit 1)) + (if (and tflag #x4) (set zbit 1)) + (if (and tflag #x8) (set sbit 1)) + (if (and tflag #x10) (set bbit 1)) + (if (and tflag #x20) (set obit 1)) + (if (and tflag #x40) (set ibit 1)) + (if (and tflag #x80) (set ubit 1)))) + ((#x4) (set (reg h-isp) (mem16 mode (reg h-sp)))) + ((#x5) (set (reg h-sp) (mem16 mode (reg h-sp)))) + ((#x6) (set (reg h-sb) (mem16 mode (reg h-sp)))) + ((#x7) (set (reg h-fb) (mem16 mode (reg h-sp)))) + ) + (set (reg h-sp) (add (reg h-sp) 2)) + ) +) +; popc dest (m16c #1) +(dni popc16.imm16 "popc dst" ((machine 16)) + ("popc ${cr16}") + (+ (f-0-4 #xE) (f-4-4 #xB) (f-8-1 0) (f-12-4 3) cr16) + (popc16-sem HI cr16) + ()) +; popc dest (m32c #1) +(dni popc32.imm16-cr1 "popc dst" ((machine 32)) + ("popc ${cr1-Unprefixed-32}") + (+ (f-0-4 #xD) (f-4-4 3) (f-8-4 #xA) (f-12-1 1) cr1-Unprefixed-32) + (popc32-cr1-sem HI cr1-Unprefixed-32) + ()) +; popc dest (m32c #2) +(dni popc32.imm16-cr2 "popc dst" ((machine 32)) + ("popc ${cr2-32}") + (+ (f-0-4 #xD) (f-4-4 3) (f-8-4 2) (f-12-1 1) cr2-32) + (popc32-cr2-sem SI cr2-32) + ()) + +(define-pmacro (pushc32-cr1-sem mode dst) + (sequence () + (set (reg h-sp) (sub (reg h-sp) 2)) + (case DFLT dst + ((#x0) (set (mem32 mode (reg h-sp)) (reg h-dct0))) + ((#x1) (set (mem32 mode (reg h-sp)) (reg h-dct1))) + ((#x2) (sequence ((HI tflag)) + (set tflag 0) + (if (eq cbit 1) (set tflag (or tflag #x1))) + (if (eq dbit 1) (set tflag (or tflag #x2))) + (if (eq zbit 1) (set tflag (or tflag #x4))) + (if (eq sbit 1) (set tflag (or tflag #x8))) + (if (eq bbit 1) (set tflag (or tflag #x10))) + (if (eq obit 1) (set tflag (or tflag #x20))) + (if (eq ibit 1) (set tflag (or tflag #x40))) + (if (eq ubit 1) (set tflag (or tflag #x80))) + (set (mem32 mode (reg h-sp)) tflag))) + ((#x3) (set (mem32 mode (reg h-sp)) (reg h-svf))) + ((#x4) (set (mem32 mode (reg h-sp)) (reg h-drc0))) + ((#x5) (set (mem32 mode (reg h-sp)) (reg h-drc1))) + ((#x6) (set (mem32 mode (reg h-sp)) (reg h-dmd0))) + ((#x7) (set (mem32 mode (reg h-sp)) (reg h-dmd1))) + ) + ) +) +(define-pmacro (pushc32-cr2-sem mode dst) + (sequence () + (set (reg h-sp) (sub (reg h-sp) 4)) + (case DFLT dst + ((#x0) (set (mem32 mode (reg h-sp)) (reg h-intb))) + ((#x1) (set (mem32 mode (reg h-sp)) (reg h-sp))) + ((#x2) (set (mem32 mode (reg h-sp)) (reg h-sb))) + ((#x3) (set (mem32 mode (reg h-sp)) (reg h-fb))) + ((#x7) (set (mem32 mode (reg h-sp)) (reg h-isp))) + ) + ) +) +(define-pmacro (pushc16-sem mode dst) + (sequence () + (set (reg h-sp) (sub (reg h-sp) 2)) + (case DFLT dst + ((#x1) (set (mem16 mode (reg h-sp)) (and (reg h-intb) #xffff))) + ((#x2) (set (mem16 mode (reg h-sp)) (and (reg h-intb) #xffff0000))) + ((#x3) (sequence ((HI tflag)) + (if (eq cbit 1) (set tflag (or tflag #x1))) + (if (eq dbit 1) (set tflag (or tflag #x2))) + (if (eq zbit 1) (set tflag (or tflag #x4))) + (if (eq sbit 1) (set tflag (or tflag #x8))) + (if (eq bbit 1) (set tflag (or tflag #x10))) + (if (eq obit 1) (set tflag (or tflag #x20))) + (if (eq ibit 1) (set tflag (or tflag #x40))) + (if (eq ubit 1) (set tflag (or tflag #x80))) + (set (mem16 mode (reg h-sp)) tflag))) + + ((#x4) (set (mem16 mode (reg h-sp)) (reg h-isp))) + ((#x5) (set (mem16 mode (reg h-sp)) (reg h-sp))) + ((#x6) (set (mem16 mode (reg h-sp)) (reg h-sb))) + ((#x7) (set (mem16 mode (reg h-sp)) (reg h-fb))) + ) + ) +) +; pushc src (m16c) +(dni pushc16.imm16 "pushc dst" ((machine 16)) + ("pushc ${cr16}") + (+ (f-0-4 #xE) (f-4-4 #xB) (f-8-1 0) (f-12-4 2) cr16) + (pushc16-sem HI cr16) + ()) +; pushc src (m32c #1) +(dni pushc32.imm16-cr1 "pushc dst" ((machine 32)) + ("pushc ${cr1-Unprefixed-32}") + (+ (f-0-4 #xD) (f-4-4 1) (f-8-4 #xA) (f-12-1 1) cr1-Unprefixed-32) + (pushc32-cr1-sem HI cr1-Unprefixed-32) + ()) +; pushc src (m32c #2) +(dni pushc32.imm16-cr2 "pushc dst" ((machine 32)) + ("pushc ${cr2-32}") + (+ (f-0-4 #xD) (f-4-4 1) (f-8-4 2) (f-12-1 1) cr2-32) + (pushc32-cr2-sem SI cr2-32) + ()) + +;------------------------------------------------------------- +; popm - pop multiple +; pushm - push multiple +;------------------------------------------------------------- + +(define-pmacro (popm-sem machine dst) + (sequence ((SI addrlen)) + (if (eq machine 16) + (set addrlen 2) + (set addrlen 4)) + (if (and dst 1) + (sequence () (set R0 (mem-mach machine HI (reg h-sp))) + (set (reg h-sp) (add (reg h-sp) 2)))) + (if (and dst 2) + (sequence () (set R1 (mem-mach machine HI (reg h-sp))) + (set (reg h-sp) (add (reg h-sp) 2)))) + (if (and dst 4) + (sequence () (set R2 (mem-mach machine HI (reg h-sp))) + (set (reg h-sp) (add (reg h-sp) 2)))) + (if (and dst 8) + (sequence () (set R3 (mem-mach machine HI (reg h-sp))) + (set (reg h-sp) (add (reg h-sp) 2)))) + (if (and dst 16) + (sequence () (set A0 (mem-mach machine HI (reg h-sp))) + (set (reg h-sp) (add (reg h-sp) addrlen)))) + (if (and dst 32) + (sequence () (set A1 (mem-mach machine HI (reg h-sp))) + (set (reg h-sp) (add (reg h-sp) addrlen)))) + (if (and dst 64) + (sequence () (set (reg h-sb) (mem-mach machine HI (reg h-sp))) + (set (reg h-sp) (add (reg h-sp) addrlen)))) + (if (eq dst 128) + (sequence () (set (reg h-fb) (mem-mach machine HI (reg h-sp))) + (set (reg h-sp) (add (reg h-sp) addrlen)))) + ) +) + +(define-pmacro (pushm-sem machine dst) + (sequence ((SI count) (SI addrlen)) + (if (eq machine 16) + (set addrlen 2) + (set addrlen 4)) + (if (eq dst 1) + (sequence () (set (reg h-sp) (sub (reg h-sp) addrlen)) + (set (mem-mach machine HI (reg h-sp)) (reg h-fb)))) + (if (and dst 2) + (sequence () (set (reg h-sp) (sub (reg h-sp) addrlen)) + (set (mem-mach machine HI (reg h-sp)) (reg h-sb)))) + (if (and dst 4) + (sequence () (set (reg h-sp) (sub (reg h-sp) addrlen)) + (set (mem-mach machine HI (reg h-sp)) A1))) + (if (and dst 8) + (sequence () (set (reg h-sp) (sub (reg h-sp) addrlen)) + (set (mem-mach machine HI (reg h-sp)) A0))) + (if (and dst 16) + (sequence () (set (reg h-sp) (sub (reg h-sp) 2)) + (set (mem-mach machine HI (reg h-sp)) R3))) + (if (and dst 32) + (sequence () (set (reg h-sp) (sub (reg h-sp) 2)) + (set (mem-mach machine HI (reg h-sp)) R2))) + (if (and dst 64) + (sequence () (set (reg h-sp) (sub (reg h-sp) 2)) + (set (mem-mach machine HI (reg h-sp)) R1))) + (if (and dst 128) + (sequence () (set (reg h-sp) (sub (reg h-sp) 2)) + (set (mem-mach machine HI (reg h-sp)) R0))) + ) +) + +(dni popm16 "popm regs" ((machine 16)) + ("popm ${Regsetpop}") + (+ (f-0-4 #xE) (f-4-4 #xD) Regsetpop) + (popm-sem 16 Regsetpop) + ()) +(dni pushm16 "pushm regs" ((machine 16)) + ("pushm ${Regsetpush}") + (+ (f-0-4 #xE) (f-4-4 #xC) Regsetpush) + (pushm-sem 16 Regsetpush) + ()) +(dni popm "popm regs" ((machine 32)) + ("popm ${Regsetpop}") + (+ (f-0-4 #x8) (f-4-4 #xE) Regsetpop) + (popm-sem 32 Regsetpop) + ()) +(dni pushm "pushm regs" ((machine 32)) + ("pushm ${Regsetpush}") + (+ (f-0-4 #x8) (f-4-4 #xF) Regsetpush) + (pushm-sem 32 Regsetpush) + ()) + +;------------------------------------------------------------- +; push - Save register/memory/immediate data +;------------------------------------------------------------- + +; TODO future: split this into .b and .w semantics +(define-pmacro (push-sem-mach mach mode dst) + (sequence ((mode b_or_w) (SI length)) + (set b_or_w -1) + (set b_or_w (srl b_or_w #x8)) + (if (eq b_or_w #x0) + (set length 1) ; .b + (if (eq b_or_w #xff) + (set length 2) ; .w + (set length 4))) ; .l + (set (reg h-sp) (sub (reg h-sp) length)) + (case DFLT length + ((1) (set (mem-mach mach QI (reg h-sp)) dst)) + ((2) (set (mem-mach mach HI (reg h-sp)) dst)) + ((4) (set (mem-mach mach SI (reg h-sp)) dst))) + ) + ) + +(define-pmacro (push-sem16 mode dst) (push-sem-mach 16 mode dst)) +(define-pmacro (push-sem32 mode dst) (push-sem-mach 32 mode dst)) + +; push.BW:G imm (m16 #1 m32 #1) +(dni push16.b.G-imm "push.b:G #Imm-16-QI" ((machine 16)) + ("push.b$G #${Imm-16-QI}") + (+ (f-0-4 7) (f-4-4 #xC) (f-8-4 #xE) (f-12-4 2) Imm-16-QI) + (push-sem16 QI Imm-16-QI) + ()) + +(dni push16.w.G-imm "push.w:G #Imm-16-HI" ((machine 16)) + ("push.w$G #${Imm-16-HI}") + (+ (f-0-4 7) (f-4-4 #xD) (f-8-4 #xE) (f-12-4 2) Imm-16-HI) + (push-sem16 HI Imm-16-HI) + ()) + +(dni push32.b.imm "push.b #Imm-8-QI" ((machine 32)) + ("push.b #${Imm-8-QI}") + (+ (f-0-4 #xA) (f-4-4 #xE) Imm-8-QI) + (push-sem32 QI Imm-8-QI) + ()) + +(dni push32.w.imm "push.w #Imm-8-HI" ((machine 32)) + ("push.w #${Imm-8-HI}") + (+ (f-0-4 #xA) (f-4-4 #xF) Imm-8-HI) + (push-sem32 HI Imm-8-HI) + ()) + +; push.BW:G src (m16 #2) +(unary-insn-mach-g 16 push (f-0-4 7) (f-4-3 2) (f-8-4 #x4) push-sem16 $G) +; push.BW:G src (m32 #2) +(unary-insn-mach 32 push #xC #x0 #xE push-sem32) + + +; push.b:S r0l/r0h (m16 #3) +(dni push16.b-s-rn "push.b:S r0[lh]" ((machine 16)) + "push.b$S ${Rn16-push-S-anyof}" + (+ (f-0-4 #x8) Rn16-push-S-anyof (f-5-3 #x2)) + (push-sem16 QI Rn16-push-S-anyof) + ()) +; push.w:S a0/a1 (m16 #4) +(dni push16.b-s-an "push.w:S a[01]" ((machine 16)) + "push.w$S ${An16-push-S-anyof}" + (+ (f-0-4 #xC) An16-push-S-anyof (f-5-3 #x2)) + (push-sem16 HI An16-push-S-anyof) + ()) + +; push.l imm32 (m32 #3) +(dni push32.l.imm "push.l #Imm-16-SI" ((machine 32)) + ("push.l #${Imm-16-SI}") + (+ (f-0-4 #xB) (f-4-4 6) (f-8-4 5) (f-12-4 3) Imm-16-SI) + (push-sem32 SI Imm-16-SI) + ()) +; push.l src (m32 #4) +(unary-insn-defn 32 16-Unprefixed SI .l push (+ (f-0-4 #xA) (f-7-1 0) dst32-16-Unprefixed-SI (f-10-2 0) (f-12-4 1)) push-sem32) + +;------------------------------------------------------------- +; pusha - push effective address +;------------------------------------------------------------ + +(define-pmacro (push16a-sem mode dst) + (sequence () + (set (reg h-sp) (sub (reg h-sp) 2)) + (set (mem16 HI (reg h-sp)) dst)) +) +(define-pmacro (push32a-sem mode dst) + (sequence () + (set (reg h-sp) (sub (reg h-sp) 4)) + (set (mem32 SI (reg h-sp)) dst)) +) +(unary-insn-defn 16 16-Mova HI "" pusha (+ (f-0-4 7) (f-4-4 #xD) (f-8-4 9) dst16-16-Mova-HI) push16a-sem) +(unary-insn-defn 32 16-Unprefixed-Mova SI "" pusha (+ (f-0-4 #xB) (f-7-1 0) dst32-16-Unprefixed-Mova-SI (f-10-2 0) (f-12-4 1)) push32a-sem) + +;------------------------------------------------------------- +; reit - return from interrupt +;------------------------------------------------------------- + +; ??? semantics +(dni reit16 "REIT" ((machine 16)) + ("reit") + (+ (f-0-4 #xF) (f-4-4 #xB)) + (nop) + ()) +(dni reit32 "REIT" ((machine 32)) + ("reit") + (+ (f-0-4 9) (f-4-4 #xE)) + (nop) + ()) + +;------------------------------------------------------------- +; rmpa - repeat multiple and addition +;------------------------------------------------------------- + +; TODO semantics +(dni rmpa16.b "rmpa.size" ((machine 16)) + ("rmpa.b") + (+ (f-0-4 7) (f-4-4 #xC) (f-8-4 #xF) (f-12-4 1)) + (nop) + ()) +(dni rmpa16.w "rmpa.size" ((machine 16)) + ("rmpa.w") + (+ (f-0-4 7) (f-4-4 #xD) (f-8-4 #xF) (f-12-4 1)) + (nop) + ()) +(dni rmpa32.b "rmpa.size" ((machine 32)) + ("rmpa.b") + (+ (f-0-4 #xB) (f-4-4 8) (f-8-4 4) (f-12-4 3)) + (nop) + ()) + +(dni rmpa32.w "rmpa.size" ((machine 32)) + ("rmpa.w") + (+ (f-0-4 #xB) (f-4-4 8) (f-8-4 5) (f-12-4 3)) + (nop) + ()) + +;------------------------------------------------------------- +; rolc - rotate left with carry +;------------------------------------------------------------- + +; TODO check semantics +; TODO future: split this into .b and .w semantics +(define-pmacro (rolc-sem mode dst) + (sequence ((mode result) (SI ocbit) (mode b_or_w) (USI mask)) + (set b_or_w -1) + (set b_or_w (srl b_or_w #x8)) + (if (eq b_or_w #x0) + (set mask #x8000) ; .b + (set mask #x80000000)) ; .w + (set ocbit cbit) + (set cbit (and dst mask)) + (set result (sll mode dst 1)) + (set result (or result ocbit)) + (set-z-and-s result) + (set dst result)) +) +; rolc.BW src,dst +(unary-insn rolc (f-0-4 7) (f-4-3 3) (f-8-4 #xA) #xB #x2 #xE rolc-sem) + +;------------------------------------------------------------- +; rorc - rotate right with carry +;------------------------------------------------------------- + +; TODO check semantics +; TODO future: split this into .b and .w semantics +(define-pmacro (rorc-sem mode dst) + (sequence ((mode result) (SI ocbit) (mode b_or_w) (USI mask) (SI shamt)) + (set b_or_w -1) + (set b_or_w (srl b_or_w #x8)) + (if (eq b_or_w #x0) + (sequence () (set mask #x7fff) (set shamt 15)) ; .b + (sequence () (set mask #x7fffffff) (set shamt 31))) ; .w + (set ocbit cbit) + (set cbit (and dst #x1)) + (set result (srl mode dst (const 1))) + (set result (or (and result mask) (sll ocbit shamt))) + (set-z-and-s result) + (set dst result)) +) +; rorc.BW src,dst +(unary-insn rorc (f-0-4 7) (f-4-3 3) (f-8-4 #xB) #xA #x2 #xE rorc-sem) + +;------------------------------------------------------------- +; rot - rotate +;------------------------------------------------------------- + +; TODO future: split this into .b and .w semantics +(define-pmacro (rot-1-sem mode src1 dst) + (sequence ((mode tmp) (mode b_or_w) (USI mask) (SI shift)) + (case DFLT src1 + ((#x0) (set shift 1)) + ((#x1) (set shift 2)) + ((#x2) (set shift 3)) + ((#x3) (set shift 4)) + ((#x4) (set shift 5)) + ((#x5) (set shift 6)) + ((#x6) (set shift 7)) + ((#x7) (set shift 8)) + ((-8) (set shift -1)) + ((-7) (set shift -2)) + ((-6) (set shift -3)) + ((-5) (set shift -4)) + ((-4) (set shift -5)) + ((-3) (set shift -6)) + ((-2) (set shift -7)) + ((-1) (set shift -8)) + (else (set shift 0)) + ) + (set b_or_w -1) + (set b_or_w (srl b_or_w #x8)) + (if (eq b_or_w #x0) + (set mask #x7fff) ; .b + (set mask #x7fffffff)) ; .w + (set tmp dst) + (if (gt mode shift 0) + (sequence () + (set tmp (rol mode tmp shift)) + (set cbit (and tmp #x1))) + (sequence () + (set tmp (ror mode tmp (mul shift -1))) + (set cbit (and tmp mask)))) + (set-z-and-s tmp) + (set dst tmp)) +) +(define-pmacro (rot-2-sem mode dst) + (sequence ((mode tmp) (mode b_or_w) (USI mask)) + (set b_or_w -1) + (set b_or_w (srl b_or_w #x8)) + (if (eq b_or_w #x0) + (set mask #x7fff) ; .b + (set mask #x7fffffff)) ; .w + (set tmp dst) + (if (gt mode (reg h-r1h) 0) + (sequence () + (set tmp (rol mode tmp (reg h-r1h))) + (set cbit (and tmp #x1))) + (sequence () + (set tmp (ror mode tmp (reg h-r1h))) + (set cbit (and tmp mask)))) + (set-z-and-s tmp) + (set dst tmp)) +) + +; rot.BW #imm4,dst +(binary-arith16-shimm4-dst-defn QI .b 0 0 rot (f-0-4 #xE) (f-4-3 0) rot-1-sem) +(binary-arith16-shimm4-dst-defn HI .w 0 1 rot (f-0-4 #xE) (f-4-3 0) rot-1-sem) +(binary-arith32-shimm4-dst-defn QI .b 0 0 rot #x7 #x2 rot-1-sem) +(binary-arith32-shimm4-dst-defn HI .w 0 1 rot #x7 #x2 rot-1-sem) +; rot.BW src,dst + +(dni rot16.b-dst "rot r1h,dest" ((machine 16)) + ("rot.b r1h,${dst16-16-QI}") + (+ (f-0-4 7) (f-4-4 #x4) (f-8-4 #x6) dst16-16-QI) + (rot-2-sem QI dst16-16-QI) + ()) +(dni rot16.w-dst "rot r1h,dest" ((machine 16)) + ("rot.w r1h,${dst16-16-HI}") + (+ (f-0-4 7) (f-4-4 #x5) (f-8-4 #x6) dst16-16-HI) + (rot-2-sem HI dst16-16-HI) + ()) + +(dni rot32.b-dst "rot r1h,dest" ((machine 32)) + ("rot.b r1h,${dst32-16-Unprefixed-QI}") + (+ (f-0-4 #xA) dst32-16-Unprefixed-QI (f-7-1 0) (f-10-2 3) (f-12-4 #xF)) + (rot-2-sem QI dst32-16-Unprefixed-QI) + ()) +(dni rot32.w-dst "rot r1h,dest" ((machine 32)) + ("rot.w r1h,${dst32-16-Unprefixed-HI}") + (+ (f-0-4 #xA) dst32-16-Unprefixed-HI (f-7-1 1) (f-10-2 3) (f-12-4 #xF)) + (rot-2-sem HI dst32-16-Unprefixed-HI) + ()) + +;------------------------------------------------------------- +; rts - return from subroutine +;------------------------------------------------------------- + +(define-pmacro (rts16-sem) + (sequence ((SI tpc)) + (set tpc (mem16 HI (reg h-sp))) + (set (reg h-sp) (add (reg h-sp) 2)) + (set tpc (or tpc (sll (mem16 QI (reg h-sp)) 16))) + (set (reg h-sp) (add (reg h-sp) 1)) + (set pc tpc) + ) +) +(define-pmacro (rts32-sem) + (sequence ((SI tpc)) + (set tpc (mem32 HI (reg h-sp))) + (set (reg h-sp) (add (reg h-sp) 2)) + (set tpc (or tpc (sll (mem32 HI (reg h-sp)) 16))) + (set (reg h-sp) (add (reg h-sp) 2)) + (set pc tpc) + ) +) + +(dni rts16 "rts" ((machine 16)) + ("rts") + (+ (f-0-4 #xF) (f-4-4 3)) + (rts16-sem) + ()) + +(dni rts32 "rts" ((machine 32)) + ("rts") + (+ (f-0-4 #xD) (f-4-4 #xF)) + (rts32-sem) + ()) + +;------------------------------------------------------------- +; sbb - subtract with borrow +;------------------------------------------------------------- + +(define-pmacro (sbb-sem mode src dst) + (sequence ((mode result)) + (set result (subc mode dst src cbit)) + (set obit (add-oflag mode dst src cbit)) + (set cbit (add-oflag mode dst src cbit)) + (set-z-and-s result) + (set dst result)) +) + +; sbb.size:G #imm,dst +(binary-arith16-imm-dst-defn QI QI .b 0 sbb X (f-0-4 7) (f-4-3 3) (f-8-4 7) sbb-sem) +(binary-arith16-imm-dst-defn HI HI .w 1 sbb X (f-0-4 7) (f-4-3 3) (f-8-4 7) sbb-sem) +(binary-arith32-imm-dst-Prefixed QI QI .b 0 sbb X #x9 #x2 #xE sbb-sem) +(binary-arith32-imm-dst-Prefixed HI HI .w 1 sbb X #x9 #x2 #xE sbb-sem) + +; sbb.BW:G src,dst +(binary-arith16-src-dst-defn QI QI .b 0 sbb X (f-0-4 #xB) (f-4-3 4) sbb-sem) +(binary-arith16-src-dst-defn HI HI .w 1 sbb X (f-0-4 #xB) (f-4-3 4) sbb-sem) +(binary-arith32-src-dst-Prefixed QI QI .b 0 sbb X #x1 #x6 sbb-sem) +(binary-arith32-src-dst-Prefixed HI HI .w 1 sbb X #x1 #x6 sbb-sem) + +;------------------------------------------------------------- +; sbjnz - subtract then jump on not zero +;------------------------------------------------------------- + +(define-pmacro (sub-jnz-sem mode src dst label) + (sequence ((mode result)) + (set result (sub mode dst src)) + (set dst result) + (if (ne result 0) + (set pc label))) +) + +; sbjnz.size #imm4,dst,label +(arith-jnz-imm4-dst sbjnz s4n (f-0-4 #xF) (f-4-3 4) #xf #x1 sub-jnz-sem) + +;------------------------------------------------------------- +; sccnd - store condition on condition (m32) +;------------------------------------------------------------- + +(define-pmacro (sccnd-sem cnd dst) + (sequence () + (set dst 0) + (case DFLT cnd + ((#x00) (if (not cbit) (set dst 1))) ;ltu nc + ((#x01) (if (or cbit zbit) (set dst 1))) ;leu + ((#x02) (if (not zbit) (set dst 1))) ;ne nz + ((#x03) (if (not sbit) (set dst 1))) ;pz + ((#x04) (if (not obit) (set dst 1))) ;no + ((#x05) (if (not (or zbit (xor sbit obit))) (set dst 1))) ;gt + ((#x06) (if (xor sbit obit) (set dst 1))) ;ge + ((#x08) (if (trunc BI cbit) (set dst 1))) ;geu c + ((#x09) (if (not (or cbit zbit)) (set dst 1))) ;gtu + ((#x0a) (if (trunc BI zbit) (set dst 1))) ;eq z + ((#x0b) (if (trunc BI sbit) (set dst 1))) ;n + ((#x0c) (if (trunc BI obit) (set dst 1))) ;o + ((#x0d) (if (or zbit (xor sbit obit)) (set dst 1))) ;le + ((#x0e) (if (xor sbit obit) (set dst 1))) ;lt + ) + ) + ) + +; scCND dst +(dni sccnd + "sccnd dst" + ((machine 32)) + "sc$sccond32 ${dst32-16-Unprefixed-HI}" + (+ (f-0-4 #xD) dst32-16-Unprefixed-HI (f-7-1 1) (f-10-2 3) sccond32) + (sccnd-sem sccond32 dst32-16-Unprefixed-HI) + ()) + +;------------------------------------------------------------- +; scmpu - string compare unequal (m32) +;------------------------------------------------------------- + +; TODO semantics +(dni scmpu.b "scmpu.b" ((machine 32)) + ("scmpu.b") + (+ (f-0-4 #xB) (f-4-4 8) (f-8-4 #xC) (f-12-4 3)) + (c-call VOID "scmpu_QI_semantics") + ()) + +(dni scmpu.w "scmpu.w" ((machine 32)) + ("scmpu.w") + (+ (f-0-4 #xB) (f-4-4 8) (f-8-4 #xD) (f-12-4 3)) + (c-call VOID "scmpu_HI_semantics") + ()) + +;------------------------------------------------------------- +; sha - shift arithmetic +;------------------------------------------------------------- + +; TODO future: split this into .b and .w semantics +(define-pmacro (sha-sem mode src1 dst) + (sequence ((mode result)(mode shift)(mode shmode)) + (case DFLT src1 + ((#x0) (set shift 1)) + ((#x1) (set shift 2)) + ((#x2) (set shift 3)) + ((#x3) (set shift 4)) + ((#x4) (set shift 5)) + ((#x5) (set shift 6)) + ((#x6) (set shift 7)) + ((#x7) (set shift 8)) + ((-8) (set shift -1)) + ((-7) (set shift -2)) + ((-6) (set shift -3)) + ((-5) (set shift -4)) + ((-4) (set shift -5)) + ((-3) (set shift -6)) + ((-2) (set shift -7)) + ((-1) (set shift -8)) + (else (set shift 0)) + ) + (set shmode -1) + (set shmode (srl shmode #x8)) + (if (lt mode shift #x0) (set result (sra mode dst (mul shift -1)))) + (if (gt mode shift 0) (set result (sll mode dst shift))) + (if (eq shmode #x0) ; QI + (sequence + ((mode cbitamt)) + (if (lt mode shift #x0) + (set cbitamt (sub #x8 shift)) ; sra + (set cbitamt (sub shift 1))) ; sll + (set cbit (srl (and (sll dst cbitamt) #x80) #x7)) + (set obit (ne (and dst #x80) (and result #x80))) + )) + (if (eq shmode #xff) ; HI + (sequence + ((mode cbitamt)) + (if (lt mode shift #x0) + (set cbitamt (sub 16 shift)) ; sra + (set cbitamt (sub shift 1))) ; sll + (set cbit (srl (and (sll dst cbitamt) #x8000) #xf)) + (set obit (ne (and dst #x8000) (and result #x8000))) + )) + (set-z-and-s result) + (set dst result)) +) +(define-pmacro (shar1h-sem mode dst) + (sequence ((mode result)(mode shmode)) + (set shmode -1) + (set shmode (srl shmode #x8)) + (if (lt mode (reg h-r1h) 0) (set result (sra mode dst (reg h-r1h)))) + (if (gt mode (reg h-r1h) 0) (set result (sll mode dst (reg h-r1h)))) + (if (eq shmode #x0) ; QI + (sequence + ((mode cbitamt)) + (if (lt mode (reg h-r1h) #x0) + (set cbitamt (sub #x8 (reg h-r1h))) ; sra + (set cbitamt (sub (reg h-r1h) 1))) ; sll + (set cbit (srl (and (sll dst cbitamt) #x80) #x7)) + (set obit (ne (and dst #x80) (and result #x80))) + )) + (if (eq shmode #xff) ; HI + (sequence + ((mode cbitamt)) + (if (lt mode (reg h-r1h) #x0) + (set cbitamt (sub 16 (reg h-r1h))) ; sra + (set cbitamt (sub (reg h-r1h) 1))) ; sll + (set cbit (srl (and (sll dst cbitamt) #x8000) #xf)) + (set obit (ne (and dst #x8000) (and result #x8000))) + )) + (set-z-and-s result) + (set dst result)) +) +; sha.BW #imm4,dst (m16 #1 m32 #1) +(binary-arith16-shimm4-dst-defn QI .b 0 0 sha (f-0-4 #xF) (f-4-3 0) sha-sem) +(binary-arith16-shimm4-dst-defn HI .w 0 1 sha (f-0-4 #xF) (f-4-3 0) sha-sem) +(binary-arith32-shimm4-dst-defn QI .b 1 0 sha #x7 #x0 sha-sem) +(binary-arith32-shimm4-dst-defn HI .w 1 1 sha #x7 #x0 sha-sem) +; sha.BW r1h,dst (m16 #2 m32 #3) +(dni sha16.b-dst "sha.b r1h,dest" ((machine 16)) + ("sha.b r1h,${dst16-16-QI}") + (+ (f-0-4 7) (f-4-4 4) (f-8-4 #xF) dst16-16-QI) + (shar1h-sem HI dst16-16-QI) + ()) +(dni sha16.w-dst "sha.w r1h,dest" ((machine 16)) + ("sha.w r1h,${dst16-16-HI}") + (+ (f-0-4 7) (f-4-4 5) (f-8-4 #xF) dst16-16-HI) + (shar1h-sem HI dst16-16-HI) + ()) +(dni sha32.b-dst "sha.b r1h,dest" ((machine 32)) + ("sha.b r1h,${dst32-16-Unprefixed-QI}") + (+ (f-0-4 #xB) dst32-16-Unprefixed-QI (f-7-1 0) (f-10-2 3) (f-12-4 #xE)) + (shar1h-sem QI dst32-16-Unprefixed-QI) + ()) +(dni sha32.w-dst "sha.w r1h,dest" ((machine 32)) + ("sha.w r1h,${dst32-16-Unprefixed-HI}") + (+ (f-0-4 #xB) dst32-16-Unprefixed-HI (f-7-1 1) (f-10-2 3) (f-12-4 #xE)) + (shar1h-sem HI dst32-16-Unprefixed-HI) + ()) +; sha.L #imm,dst (m16 #3) +(dni sha16-L-imm-r2r0 "sha.L #Imm-sh-12-s4,r2r0" ((machine 16)) + "sha.l #${Imm-sh-12-s4},r2r0" + (+ (f-0-4 #xE) (f-4-4 #xB) (f-8-4 #xA) Imm-sh-12-s4) + (sha-sem SI Imm-sh-12-s4 (reg h-r2r0)) + ()) +(dni sha16-L-imm-r3r1 "sha.L #Imm-sh-12-s4,r3r1" ((machine 16)) + "sha.l #${Imm-sh-12-s4},r3r1" + (+ (f-0-4 #xE) (f-4-4 #xB) (f-8-4 #xB) Imm-sh-12-s4) + (sha-sem SI Imm-sh-12-s4 (reg h-r3r1)) + ()) +; sha.L r1h,dst (m16 #4) +(dni sha16-L-r1h-r2r0 "sha.L r1h,r2r0" ((machine 16)) + "sha.l r1h,r2r0" + (+ (f-0-4 #xE) (f-4-4 #xB) (f-8-4 2) (f-12-4 1)) + (sha-sem SI (reg h-r1h) (reg h-r2r0)) + ()) +(dni sha16-L-r1h-r3r1 "sha.L r1h,r3r1" ((machine 16)) + "sha.l r1h,r3r1" + (+ (f-0-4 #xE) (f-4-4 #xB) (f-8-4 3) (f-12-4 1)) + (sha-sem SI (reg h-r1h) (reg h-r3r1)) + ()) +; sha.L #imm8,dst (m32 #2) +(binary-arith32-imm-dst-defn QI SI .l 0 sha X #xA #x2 #x1 sha-sem) +; sha.L r1h,dst (m32 #4) +(dni sha32.l-dst "sha.l r1h,dest" ((machine 32)) + ("sha.l r1h,${dst32-16-Unprefixed-SI}") + (+ (f-0-4 #xC) dst32-16-Unprefixed-SI (f-7-1 0) (f-10-2 1) (f-12-4 1)) + (shar1h-sem QI dst32-16-Unprefixed-SI) + ()) + +;------------------------------------------------------------- +; shanc - shift arithmetic non carry (m32) +;------------------------------------------------------------- + +; TODO check semantics +; shanc.L #imm8,dst +(binary-arith32-imm-dst-defn QI SI .l 0 shanc X #xC #x2 #x1 sha-sem) + +;------------------------------------------------------------- +; shl - shift logical +;------------------------------------------------------------- + +; TODO future: split this into .b and .w semantics +(define-pmacro (shl-sem mode src1 dst) + (sequence ((mode result)(mode shift)(mode shmode)) + (case DFLT src1 + ((#x0) (set shift 1)) + ((#x1) (set shift 2)) + ((#x2) (set shift 3)) + ((#x3) (set shift 4)) + ((#x4) (set shift 5)) + ((#x5) (set shift 6)) + ((#x6) (set shift 7)) + ((#x7) (set shift 8)) + ((-8) (set shift -1)) + ((-7) (set shift -2)) + ((-6) (set shift -3)) + ((-5) (set shift -4)) + ((-4) (set shift -5)) + ((-3) (set shift -6)) + ((-2) (set shift -7)) + ((-1) (set shift -8)) + (else (set shift 0)) + ) + (set shmode -1) + (set shmode (srl shmode #x8)) + (if (lt mode shift #x0) (set result (srl mode dst (mul shift -1)))) + (if (gt mode shift 0) (set result (sll mode dst shift))) + (if (eq shmode #x0) ; QI + (sequence + ((mode cbitamt)) + (if (lt mode shift #x0) + (set cbitamt (sub #x8 shift)); srl + (set cbitamt (sub shift 1))) ; sll + (set cbit (srl (and (sll dst cbitamt) #x80) #x7)) + (set obit (ne (and dst #x80) (and result #x80))) + )) + (if (eq shmode #xff) ; HI + (sequence + ((mode cbitamt)) + (if (lt mode shift #x0) + (set cbitamt (sub 16 shift)) ; srl + (set cbitamt (sub shift 1))) ; sll + (set cbit (srl (and (sll dst cbitamt) #x8000) #xf)) + (set obit (ne (and dst #x8000) (and result #x8000))) + )) + (set-z-and-s result) + (set dst result)) + ) +(define-pmacro (shlr1h-sem mode dst) + (sequence ((mode result)(mode shmode)) + (set shmode -1) + (set shmode (srl shmode #x8)) + (if (lt mode (reg h-r1h) 0) (set result (srl mode dst (reg h-r1h)))) + (if (gt mode (reg h-r1h) 0) (set result (sll mode dst (reg h-r1h)))) + (if (eq shmode #x0) ; QI + (sequence + ((mode cbitamt)) + (if (lt mode (reg h-r1h) #x0) + (set cbitamt (sub #x8 (reg h-r1h))) ; srl + (set cbitamt (sub (reg h-r1h) 1))) ; sll + (set cbit (srl (and (sll dst cbitamt) #x80) #x7)) + (set obit (ne (and dst #x80) (and result #x80))) + )) + (if (eq shmode #xff) ; HI + (sequence + ((mode cbitamt)) + (if (lt mode (reg h-r1h) #x0) + (set cbitamt (sub 16 (reg h-r1h))) ; srl + (set cbitamt (sub (reg h-r1h) 1))) ; sll + (set cbit (srl (and (sll dst cbitamt) #x8000) #xf)) + (set obit (ne (and dst #x8000) (and result #x8000))) + )) + (set-z-and-s result) + (set dst result)) + ) +; shl.BW #imm4,dst (m16 #1 m32 #1) +(binary-arith16-shimm4-dst-defn QI .b 0 0 shl (f-0-4 #xE) (f-4-3 4) shl-sem) +(binary-arith16-shimm4-dst-defn HI .w 0 1 shl (f-0-4 #xE) (f-4-3 4) shl-sem) +(binary-arith32-shimm4-dst-defn QI .b 0 0 shl #x7 #x0 shl-sem) +(binary-arith32-shimm4-dst-defn HI .w 0 1 shl #x7 #x0 shl-sem) +; shl.BW r1h,dst (m16 #2 m32 #3) +(dni shl16.b-dst "shl.b r1h,dest" ((machine 16)) + ("shl.b r1h,${dst16-16-QI}") + (+ (f-0-4 7) (f-4-4 4) (f-8-4 #xE) dst16-16-QI) + (shlr1h-sem HI dst16-16-QI) + ()) +(dni shl16.w-dst "shl.w r1h,dest" ((machine 16)) + ("shl.w r1h,${dst16-16-HI}") + (+ (f-0-4 7) (f-4-4 5) (f-8-4 #xE) dst16-16-HI) + (shlr1h-sem HI dst16-16-HI) + ()) +(dni shl32.b-dst "shl.b r1h,dest" ((machine 32)) + ("shl.b r1h,${dst32-16-Unprefixed-QI}") + (+ (f-0-4 #xA) dst32-16-Unprefixed-QI (f-7-1 0) (f-10-2 3) (f-12-4 #xE)) + (shlr1h-sem QI dst32-16-Unprefixed-QI) + ()) +(dni shl32.w-dst "shl.w r1h,dest" ((machine 32)) + ("shl.w r1h,${dst32-16-Unprefixed-HI}") + (+ (f-0-4 #xA) dst32-16-Unprefixed-HI (f-7-1 1) (f-10-2 3) (f-12-4 #xE)) + (shlr1h-sem HI dst32-16-Unprefixed-HI) + ()) +; shl.L #imm,dst (m16 #3) +(dni shl16-L-imm-r2r0 "shl.L #Imm-sh-12-s4,r2r0" ((machine 16)) + "shl.l #${Imm-sh-12-s4},r2r0" + (+ (f-0-4 #xE) (f-4-4 #xB) (f-8-4 #x8) Imm-sh-12-s4) + (shl-sem SI Imm-sh-12-s4 (reg h-r2r0)) + ()) +(dni shl16-L-imm-r3r1 "shl.L #Imm-sh-12-s4,r3r1" ((machine 16)) + "shl.l #${Imm-sh-12-s4},r3r1" + (+ (f-0-4 #xE) (f-4-4 #xB) (f-8-4 #x9) Imm-sh-12-s4) + (shl-sem SI Imm-sh-12-s4 (reg h-r3r1)) + ()) +; shl.L r1h,dst (m16 #4) +(dni shl16-L-r1h-r2r0 "shl.L r1h,r2r0" ((machine 16)) + "shl.l r1h,r2r0" + (+ (f-0-4 #xE) (f-4-4 #xB) (f-8-4 0) (f-12-4 1)) + (shl-sem SI (reg h-r1h) (reg h-r2r0)) + ()) +(dni shl16-L-r1h-r3r1 "shl.L r1h,r3r1" ((machine 16)) + "shl.l r1h,r3r1" + (+ (f-0-4 #xE) (f-4-4 #xB) (f-8-4 1) (f-12-4 1)) + (shl-sem SI (reg h-r1h) (reg h-r3r1)) + ()) +; shl.L #imm8,dst (m32 #2) +(binary-arith32-imm-dst-defn QI SI .l 0 shl X #x9 #x2 #x1 shl-sem) +; shl.L r1h,dst (m32 #4) +(dni shl32.l-dst "shl.l r1h,dest" ((machine 32)) + ("shl.l r1h,${dst32-16-Unprefixed-SI}") + (+ (f-0-4 #xC) dst32-16-Unprefixed-SI (f-7-1 0) (f-10-2 0) (f-12-4 1)) + (shlr1h-sem QI dst32-16-Unprefixed-SI) + ()) + +;------------------------------------------------------------- +; shlnc - shift logical non carry +;------------------------------------------------------------- + +; TODO check semantics +; shlnc.L #imm8,dst +(binary-arith32-imm-dst-defn QI SI .l 0 shlnc X #x8 #x2 #x1 shl-sem) + +;------------------------------------------------------------- +; sin - string input (m32) +;------------------------------------------------------------- + +; TODO semantics +(dni sin32.b "sin" ((machine 32)) + ("sin.b") + (+ (f-0-4 #xB) (f-4-4 2) (f-8-4 8) (f-12-4 3)) + (c-call VOID "sin_QI_semantics") + ()) + +(dni sin32.w "sin" ((machine 32)) + ("sin.w") + (+ (f-0-4 #xB) (f-4-4 2) (f-8-4 9) (f-12-4 3)) + (c-call VOID "sin_HI_semantics") + ()) + +;------------------------------------------------------------- +; smovb - string move backward +;------------------------------------------------------------- + +; TODO semantics +(dni smovb16.b "smovb.b" ((machine 16)) + ("smovb.b") + (+ (f-0-4 7) (f-4-4 #xC) (f-8-4 #xE) (f-12-4 9)) + (c-call VOID "smovb_QI_semantics") + ()) + +(dni smovb16.w "smovb.w" ((machine 16)) + ("smovb.w") + (+ (f-0-4 7) (f-4-4 #xD) (f-8-4 #xE) (f-12-4 9)) + (c-call VOID "smovb_HI_semantics") + ()) + +(dni smovb32.b "smovb.b" ((machine 32)) + ("smovb.b") + (+ (f-0-4 #xB) (f-4-4 6) (f-8-4 8) (f-12-4 3)) + (c-call VOID "smovb_QI_semantics") + ()) + +(dni smovb32.w "smovb.w" ((machine 32)) + ("smovb.w") + (+ (f-0-4 #xB) (f-4-4 6) (f-8-4 9) (f-12-4 3)) + (c-call VOID "smovb_HI_semantics") + ()) + +;------------------------------------------------------------- +; smovf - string move forward (m32) +;------------------------------------------------------------- + +; TODO semantics +(dni smovf16.b "smovf.b" ((machine 16)) + ("smovf.b") + (+ (f-0-4 7) (f-4-4 #xC) (f-8-4 #xE) (f-12-4 8)) + (c-call VOID "smovf_QI_semantics") + ()) + +(dni smovf16.w "smovf.w" ((machine 16)) + ("smovf.w") + (+ (f-0-4 7) (f-4-4 #xD) (f-8-4 #xE) (f-12-4 8)) + (c-call VOID "smovf_HI_semantics") + ()) + +(dni smovf32.b "smovf.b" ((machine 32)) + ("smovf.b") + (+ (f-0-4 #xB) (f-4-4 0) (f-8-4 8) (f-12-4 3)) + (c-call VOID "smovf_QI_semantics") + ()) + +(dni smovf32.w "smovf.w" ((machine 32)) + ("smovf.w") + (+ (f-0-4 #xB) (f-4-4 0) (f-8-4 9) (f-12-4 3)) + (c-call VOID "smovf_HI_semantics") + ()) + +;------------------------------------------------------------- +; smovu - string move unequal (m32) +;------------------------------------------------------------- + +; TODO semantics +(dni smovu.b "smovu.b" ((machine 32)) + ("smovu.b") + (+ (f-0-4 #xB) (f-4-4 8) (f-8-4 8) (f-12-4 3)) + (c-call VOID "smovu_QI_semantics") + ()) + +(dni smovu.w "smovu.w" ((machine 32)) + ("smovu.w") + (+ (f-0-4 #xB) (f-4-4 8) (f-8-4 9) (f-12-4 3)) + (c-call VOID "smovu_HI_semantics") + ()) + +;------------------------------------------------------------- +; sout - string output (m32) +;------------------------------------------------------------- + +; TODO semantics +(dni sout.b "sout.b" ((machine 32)) + ("sout.b") + (+ (f-0-4 #xB) (f-4-4 4) (f-8-4 8) (f-12-4 3)) + (c-call VOID "sout_QI_semantics") + ()) + +(dni sout.w "sout" ((machine 32)) + ("sout.w") + (+ (f-0-4 #xB) (f-4-4 4) (f-8-4 9) (f-12-4 3)) + (c-call VOID "sout_HI_semantics") + ()) + +;------------------------------------------------------------- +; sstr - string store +;------------------------------------------------------------- + +; TODO semantics +(dni sstr16.b "sstr.b" ((machine 16)) + ("sstr.b") + (+ (f-0-4 7) (f-4-4 #xC) (f-8-4 #xE) (f-12-4 #xA)) + (c-call VOID "sstr_QI_semantics") + ()) + +(dni sstr16.w "sstr.w" ((machine 16)) + ("sstr.w") + (+ (f-0-4 7) (f-4-4 #xD) (f-8-4 #xE) (f-12-4 #xA)) + (c-call VOID "sstr_HI_semantics") + ()) + +(dni sstr.b "sstr" ((machine 32)) + ("sstr.b") + (+ (f-0-4 #xB) (f-4-4 8) (f-8-4 0) (f-12-4 3)) + (c-call VOID "sstr_QI_semantics") + ()) + +(dni sstr.w "sstr" ((machine 32)) + ("sstr.w") + (+ (f-0-4 #xB) (f-4-4 8) (f-8-4 1) (f-12-4 3)) + (c-call VOID "sstr_HI_semantics") + ()) + +;------------------------------------------------------------- +; stnz - store on not zero +;------------------------------------------------------------- + +(define-pmacro (stnz-sem mode src dst) + (sequence () + (if (ne zbit (const 1)) + (set dst src))) +) +; stnz #imm8,dst3 (m16) +(binary-arith16-b-S-imm8-dst3 stnz "" (f-0-4 #xD) (f-4-1 0) stnz-sem) +; stnz.BW #imm,dst (m32) +(binary-arith32-imm-dst-defn QI QI .b 0 stnz X #x9 #x1 #xF stnz-sem) +(binary-arith32-imm-dst-defn HI HI .w 1 stnz X #x9 #x1 #xF stnz-sem) + +;------------------------------------------------------------- +; stz - store on zero +;------------------------------------------------------------- + +(define-pmacro (stz-sem mode src dst) + (sequence () + (if (eq zbit (const 1)) + (set dst src))) +) +; stz #imm8,dst3 (m16) +(binary-arith16-b-S-imm8-dst3 stz "" (f-0-4 #xC) (f-4-1 1) stz-sem) +; stz.BW #imm,dst (m32) +(binary-arith32-imm-dst-defn QI QI .b 0 stz X #x9 #x0 #xF stz-sem) +(binary-arith32-imm-dst-defn HI HI .w 1 stz X #x9 #x0 #xF stz-sem) + +;------------------------------------------------------------- +; stzx - store on zero extention +;------------------------------------------------------------- + +(define-pmacro (stzx-sem mode src1 src2 dst) + (sequence () + (if (eq zbit (const 1)) + (set dst src1) + (set dst src2))) + ) +; stzx #imm8,dst3 (m16) +(dni stzx16-imm8-imm8-r0h "stzx #Imm8,#Imm8,r0h" ((machine 16)) + ("stzx #${Imm-8-QI},#${Imm-16-QI},r0h") + (+ (f-0-4 #xD) (f-4-4 #xB) Imm-8-QI Imm-16-QI) + (stzx-sem QI Imm-8-QI Imm-16-QI (reg h-r0h)) + ()) +(dni stzx16-imm8-imm8-r0l "stzx #Imm8,#Imm8,r0l" ((machine 16)) + ("stzx #${Imm-8-QI},#${Imm-16-QI},r0l") + (+ (f-0-4 #xD) (f-4-4 #xC) Imm-8-QI Imm-16-QI) + (stzx-sem QI Imm-8-QI Imm-16-QI (reg h-r0l)) + ()) +(dni stzx16-imm8-imm8-dsp8sb "stzx #Imm8,#Imm8,dsp8[sb]" ((machine 16)) + ("stzx #${Imm-8-QI},#${Imm-24-QI},${Dsp-16-u8}[sb]") + (+ (f-0-4 #xD) (f-4-4 #xD) Imm-8-QI Dsp-16-u8 Imm-24-QI) + (stzx-sem QI Imm-8-QI Imm-16-QI (mem16 QI (add (reg h-sb) Dsp-24-u8))) + ()) +(dni stzx16-imm8-imm8-dsp8fb "stzx #Imm8,#Imm8,dsp8[fb]" ((machine 16)) + ("stzx #${Imm-8-QI},#${Imm-24-QI},${Dsp-16-s8}[fb]") + (+ (f-0-4 #xD) (f-4-4 #xE) Imm-8-QI Dsp-16-s8 Imm-24-QI) + (stzx-sem QI Imm-8-QI Imm-24-QI (mem16 QI (add (reg h-fb) Dsp-16-s8))) + ()) +(dni stzx16-imm8-imm8-abs16 "stzx #Imm8,#Imm8,abs16" ((machine 16)) + ("stzx #${Imm-8-QI},#${Imm-32-QI},${Dsp-16-u16}") + (+ (f-0-4 #xD) (f-4-4 #xF) Imm-8-QI Dsp-16-u16 Imm-32-QI) + (stzx-sem QI Imm-8-QI Imm-32-QI (mem16 QI Dsp-16-u16)) + ()) +; stzx.BW #imm,dst (m32) +(insn-imm1-imm2-dst-Unprefixed stzx #x9 #x3 #xF stzx-sem) + +;------------------------------------------------------------- +; subx - subtract extend (m32) +;------------------------------------------------------------- + +(define-pmacro (subx-sem mode src1 dst) + (sequence ((mode result)) + (set result (sub mode dst (ext mode src1))) + (set obit (sub-oflag mode dst (ext mode src1) 0)) + (set cbit (sub-cflag mode dst (ext mode src1) 0)) + (set dst result) + (set-z-and-s result))) +; subx #imm8,dst +(binary-arith32-imm-dst-defn QI SI "" 0 subx G #x9 #x1 #x1 subx-sem) +; subx src,dst +(binary-arith32-src-dst-defn QI SI "" 0 subx G #x1 #x0 subx-sem) + +;------------------------------------------------------------- +; tst - test +;------------------------------------------------------------- + +(define-pmacro (tst-sem mode src1 dst) + (sequence ((mode result)) + (set result (and mode dst src1)) + (set-z-and-s result)) +) + +; tst.BW #imm,dst (m16 #1 m32 #1) +(binary-arith-imm-dst tst G (f-0-4 7) (f-4-3 3) (f-8-4 0) #x9 #x3 #xE tst-sem) +; tst.BW src,dst (m16 #2 m32 #3) +(binary-arith16-src-dst-defn QI QI .b 0 tst X (f-0-4 #x8) (f-4-3 0) tst-sem) +(binary-arith16-src-dst-defn HI HI .w 1 tst X (f-0-4 #x8) (f-4-3 0) tst-sem) +(binary-arith32-src-dst-Prefixed QI QI .b 0 tst G #x1 #x9 tst-sem) +(binary-arith32-src-dst-Prefixed HI HI .w 1 tst G #x1 #x9 tst-sem) +; tst.BW:S #imm,dst2 (m32 #2) +(binary-arith32-s-imm-dst QI .b 0 tst #x0 #x6 tst-sem) +(binary-arith32-s-imm-dst HI .w 1 tst #x0 #x6 tst-sem) + +;------------------------------------------------------------- +; und - undefined +;------------------------------------------------------------- + +(dni und16 "und" ((machine 16)) + ("und") + (+ (f-0-4 #xF) (f-4-4 #xF)) + (nop) + ()) + +(dni und32 "und" ((machine 32)) + ("und") + (+ (f-0-4 #xF) (f-4-4 #xF)) + (nop) + ()) + +;------------------------------------------------------------- +; wait +;------------------------------------------------------------- + +; ??? semantics +(dni wait16 "wait" ((machine 16)) + ("wait") + (+ (f-0-4 7) (f-4-4 #xD) (f-8-4 #xF) (f-12-4 3)) + (nop) + ()) + +(dni wait "wait" ((machine 32)) + ("wait") + (+ (f-0-4 #xB) (f-4-4 2) (f-8-4 0) (f-12-4 3)) + (nop) + ()) + +;------------------------------------------------------------- +; xchg - exchange +;------------------------------------------------------------- + +(define-pmacro (xchg-sem mode src dst) + (sequence ((mode result)) + (set result src) + (set src dst) + (set dst result)) + ) +(define-pmacro (xchg16-defn mode sz szc src srcreg) + (dni (.sym xchg16 sz - srcreg) + (.str "xchg" sz "-" srcreg ",dst16-16-" mode) + ((machine 16)) + (.str "xchg." sz " " srcreg ",${dst16-16-" mode "}") + (+ (f-0-4 #x7) (f-4-3 #x5) (f-7-1 szc) (f-8-2 0) (f-10-2 src) (.sym dst16-16- mode)) + (xchg-sem mode (reg (.sym h- srcreg)) (.sym dst16-16- mode)) + ()) +) +(xchg16-defn QI b 0 0 r0l) +(xchg16-defn QI b 0 1 r0h) +(xchg16-defn QI b 0 2 r1l) +(xchg16-defn QI b 0 3 r1h) +(xchg16-defn HI w 1 0 r0) +(xchg16-defn HI w 1 1 r1) +(xchg16-defn HI w 1 2 r2) +(xchg16-defn HI w 1 3 r3) +(define-pmacro (xchg32-defn mode sz szc src srcreg) + (dni (.sym xchg32 sz - srcreg) + (.str "xchg" sz "-" srcreg ",dst32-16-Unprefixed-" mode) + ((machine 32)) + (.str "xchg." sz " " srcreg ",${dst32-16-Unprefixed-" mode "}") + (+ (f-0-4 #xD) (.sym dst32-16-Unprefixed- mode) (f-7-1 szc) (f-10-2 0) (f-12-1 1) (f-13-3 src)) + (xchg-sem mode (reg (.sym h- srcreg)) (.sym dst32-16-Unprefixed- mode)) + ()) +) +(xchg32-defn QI b 0 0 r0l) +(xchg32-defn QI b 0 1 r1l) +(xchg32-defn QI b 0 2 a0) +(xchg32-defn QI b 0 3 a1) +(xchg32-defn QI b 0 4 r0h) +(xchg32-defn QI b 0 5 r1h) +(xchg32-defn HI w 1 0 r0) +(xchg32-defn HI w 1 1 r1) +(xchg32-defn HI w 1 2 a0) +(xchg32-defn HI w 1 3 a1) +(xchg32-defn HI w 1 4 r2) +(xchg32-defn HI w 1 5 r3) + +;------------------------------------------------------------- +; xor - exclusive or +;------------------------------------------------------------- + +(define-pmacro (xor-sem mode src1 dst) + (sequence ((mode result)) + (set result (xor mode src1 dst)) + (set-z-and-s result) + (set dst result)) +) + +; xor.BW #imm,dst (m16 #1 m32 #1) +(binary-arith-imm-dst xor G (f-0-4 7) (f-4-3 3) (f-8-4 1) #x9 #x0 #xE xor-sem) +; xor.BW src,dst (m16 #3 m32 #3) +(binary-arith-src-dst xor G (f-0-4 #x8) (f-4-3 4) #x1 #x9 xor-sem) + +;------------------------------------------------------------- +; Widening +;------------------------------------------------------------- + +(define-pmacro (exts-sem smode dmode src dst) + (set dst (ext dmode (trunc smode src))) +) +(define-pmacro (extz-sem smode dmode src dst) + (set dst (zext dmode (trunc smode src))) +) + +; exts.b dst for m16c +(ext16-defn QI HI .b 0 exts (f-0-4 7) (f-4-3 6) (f-8-4 6) exts-sem) + +; exts.w r0 for m16c +(dni exts16.w-r0 + "exts.w r0" + ((machine 16)) + "exts.w r0" + (+ (f-0-4 #x7) (f-4-4 #xC) (f-8-4 #xF) (f-12-4 3)) + (exts-sem HI SI R0 R2R0) + ()) + +; exts.size dst for m32c +(ext32-defn QI HI .b 0 exts (f-0-4 #xC) (f-10-2 1) (f-12-4 #xE) exts-sem) +(ext32-defn HI SI .w 1 exts (f-0-4 #xC) (f-10-2 1) (f-12-4 #xE) exts-sem) +; exts.b src,dst for m32c +(ext32-binary-defn exts .b #x1 #x7 exts-sem) + +; extz.b src,dst for m32c +(ext32-binary-defn extz "" #x1 #xB extz-sem) + +;------------------------------------------------------------- +; Indirect +;------------------------------------------------------------- + +; TODO semantics +(dni srcind "SRC-INDIRECT" ((machine 32)) + ("src-indirect") + (+ (f-0-4 4) (f-4-4 1)) + (set (reg h-src-indirect) 1) + ()) + +(dni destind "DEST-INDIRECT" ((machine 32)) + ("dest-indirect") + (+ (f-0-4 0) (f-4-4 9)) + (set (reg h-dst-indirect) 1) + ()) + +(dni srcdestind "SRC-DEST-INDIRECT" ((machine 32)) + ("src-dest-indirect") + (+ (f-0-4 4) (f-4-4 9)) + (sequence () (set (reg h-src-indirect) 1) (set (reg h-dst-indirect) 1)) + ()) diff --git a/cpu/m32c.opc b/cpu/m32c.opc new file mode 100644 index 00000000000..40c3075fac8 --- /dev/null +++ b/cpu/m32c.opc @@ -0,0 +1,1187 @@ +/* m32c opcode support. -*- C -*- + + Copyright 2005, 2007, 2009 Free Software Foundation, Inc. + + Contributed by Red Hat Inc; developed under contract from Renesas + + 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. */ + + +/* This file is an addendum to m32c.cpu. Heavy use of C code isn't + appropriate in .cpu files, so it resides here. This especially applies + to assembly/disassembly where parsing/printing can be quite involved. + Such things aren't really part of the specification of the cpu, per se, + so .cpu files provide the general framework and .opc files handle the + nitty-gritty details as necessary. + + Each section is delimited with start and end markers. + + <arch>-opc.h additions use: "-- opc.h" + <arch>-opc.c additions use: "-- opc.c" + <arch>-asm.c additions use: "-- asm.c" + <arch>-dis.c additions use: "-- dis.c" + <arch>-ibd.h additions use: "-- ibd.h". */ + +/* -- opc.h */ + +/* Needed for RTL's 'ext' and 'trunc' operators. */ +#include "cgen-types.h" +#include "cgen-ops.h" + +/* We can't use the default hash size because many bits are used by + operands. */ +#define CGEN_DIS_HASH_SIZE 1 +#define CGEN_DIS_HASH(buf, value) 0 +#define CGEN_VERBOSE_ASSEMBLER_ERRORS +#define CGEN_VALIDATE_INSN_SUPPORTED + +extern int m32c_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *); + +#define CGEN_ASM_HASH_SIZE 0xffff +#define CGEN_ASM_HASH(mnem) m32c_asm_hash ((mnem)) + +/* -- */ + +/* -- opc.c */ +static unsigned int +m32c_asm_hash (const char *mnem) +{ + unsigned int h; + + /* The length of the mnemonic for the Jcnd insns is 1. Hash jsri. */ + if (mnem[0] == 'j' && mnem[1] != 's') + return 'j'; + + /* Don't hash scCND */ + if (mnem[0] == 's' && mnem[1] == 'c') + return 's'; + + /* Don't hash bmCND */ + if (mnem[0] == 'b' && mnem[1] == 'm') + return 'b'; + + for (h = 0; *mnem && *mnem != ' ' && *mnem != ':'; ++mnem) + h += *mnem; + return h % CGEN_ASM_HASH_SIZE; +} + +/* -- asm.c */ +#include "safe-ctype.h" + +#define MACH_M32C 5 /* Must match md_begin. */ + +static int +m32c_cgen_isa_register (const char **strp) + { + int u; + const char *s = *strp; + static char * m32c_register_names [] = + { + "r0", "r1", "r2", "r3", "r0l", "r0h", "r1l", "r1h", + "a0", "a1", "r2r0", "r3r1", "sp", "fb", "dct0", "dct1", "flg", "svf", + "drc0", "drc1", "dmd0", "dmd1", "intb", "svp", "vct", "isp", "dma0", + "dma1", "dra0", "dra1", "dsa0", "dsa1", 0 + }; + + for (u = 0; m32c_register_names[u]; u++) + { + int len = strlen (m32c_register_names[u]); + + if (memcmp (m32c_register_names[u], s, len) == 0 + && (s[len] == 0 || ! ISALNUM (s[len]))) + return 1; + } + return 0; +} + +#define PARSE_UNSIGNED \ + do \ + { \ + /* Don't successfully parse literals beginning with '['. */ \ + if (**strp == '[') \ + return "Invalid literal"; /* Anything -- will not be seen. */ \ + \ + errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);\ + if (errmsg) \ + return errmsg; \ + } \ + while (0) + +#define PARSE_SIGNED \ + do \ + { \ + /* Don't successfully parse literals beginning with '['. */ \ + if (**strp == '[') \ + return "Invalid literal"; /* Anything -- will not be seen. */ \ + \ + errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); \ + if (errmsg) \ + return errmsg; \ + } \ + while (0) + +static const char * +parse_unsigned6 (CGEN_CPU_DESC cd, const char **strp, + int opindex, unsigned long *valuep) +{ + const char *errmsg = 0; + unsigned long value; + + PARSE_UNSIGNED; + + if (value > 0x3f) + return _("imm:6 immediate is out of range"); + + *valuep = value; + return 0; +} + +static const char * +parse_unsigned8 (CGEN_CPU_DESC cd, const char **strp, + int opindex, unsigned long *valuep) +{ + const char *errmsg = 0; + unsigned long value; + long have_zero = 0; + + if (strncasecmp (*strp, "%dsp8(", 6) == 0) + { + enum cgen_parse_operand_result result_type; + bfd_vma value; + const char *errmsg; + + *strp += 6; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_8, + & result_type, & value); + if (**strp != ')') + return _("missing `)'"); + (*strp) ++; + + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + { + return _("%dsp8() takes a symbolic address, not a number"); + } + *valuep = value; + return errmsg; + } + + if (strncmp (*strp, "0x0", 3) == 0 + || (**strp == '0' && *(*strp + 1) != 'x')) + have_zero = 1; + + PARSE_UNSIGNED; + + if (value > 0xff) + return _("dsp:8 immediate is out of range"); + + /* If this field may require a relocation then use larger dsp16. */ + if (! have_zero && value == 0) + return _("dsp:8 immediate is out of range"); + + *valuep = value; + return 0; +} + +static const char * +parse_signed4 (CGEN_CPU_DESC cd, const char **strp, + int opindex, signed long *valuep) +{ + const char *errmsg = 0; + signed long value; + long have_zero = 0; + + if (strncmp (*strp, "0x0", 3) == 0 + || (**strp == '0' && *(*strp + 1) != 'x')) + have_zero = 1; + + PARSE_SIGNED; + + if (value < -8 || value > 7) + return _("Immediate is out of range -8 to 7"); + + /* If this field may require a relocation then use larger dsp16. */ + if (! have_zero && value == 0) + return _("Immediate is out of range -8 to 7"); + + *valuep = value; + return 0; +} + +static const char * +parse_signed4n (CGEN_CPU_DESC cd, const char **strp, + int opindex, signed long *valuep) +{ + const char *errmsg = 0; + signed long value; + long have_zero = 0; + + if (strncmp (*strp, "0x0", 3) == 0 + || (**strp == '0' && *(*strp + 1) != 'x')) + have_zero = 1; + + PARSE_SIGNED; + + if (value < -7 || value > 8) + return _("Immediate is out of range -7 to 8"); + + /* If this field may require a relocation then use larger dsp16. */ + if (! have_zero && value == 0) + return _("Immediate is out of range -7 to 8"); + + *valuep = -value; + return 0; +} + +static const char * +parse_signed8 (CGEN_CPU_DESC cd, const char **strp, + int opindex, signed long *valuep) +{ + const char *errmsg = 0; + signed long value; + + if (strncasecmp (*strp, "%hi8(", 5) == 0) + { + enum cgen_parse_operand_result result_type; + bfd_vma value; + const char *errmsg; + + *strp += 5; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32C_HI8, + & result_type, & value); + if (**strp != ')') + return _("missing `)'"); + (*strp) ++; + + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + { + value >>= 16; + } + *valuep = value; + return errmsg; + } + + PARSE_SIGNED; + + if (value <= 255 && value > 127) + value -= 0x100; + + if (value < -128 || value > 127) + return _("dsp:8 immediate is out of range"); + + *valuep = value; + return 0; +} + +static const char * +parse_unsigned16 (CGEN_CPU_DESC cd, const char **strp, + int opindex, unsigned long *valuep) +{ + const char *errmsg = 0; + unsigned long value; + long have_zero = 0; + + if (strncasecmp (*strp, "%dsp16(", 7) == 0) + { + enum cgen_parse_operand_result result_type; + bfd_vma value; + const char *errmsg; + + *strp += 7; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_16, + & result_type, & value); + if (**strp != ')') + return _("missing `)'"); + (*strp) ++; + + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + { + return _("%dsp16() takes a symbolic address, not a number"); + } + *valuep = value; + return errmsg; + } + + /* Don't successfully parse literals beginning with '['. */ + if (**strp == '[') + return "Invalid literal"; /* Anything -- will not be seen. */ + + /* Don't successfully parse register names. */ + if (m32c_cgen_isa_register (strp)) + return "Invalid literal"; /* Anything -- will not be seen. */ + + if (strncmp (*strp, "0x0", 3) == 0 + || (**strp == '0' && *(*strp + 1) != 'x')) + have_zero = 1; + + errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value); + if (errmsg) + return errmsg; + + if (value > 0xffff) + return _("dsp:16 immediate is out of range"); + + /* If this field may require a relocation then use larger dsp24. */ + if (cd->machs == MACH_M32C && ! have_zero && value == 0 + && (strncmp (*strp, "[a", 2) == 0 + || **strp == ',' + || **strp == 0)) + return _("dsp:16 immediate is out of range"); + + *valuep = value; + return 0; +} + +static const char * +parse_signed16 (CGEN_CPU_DESC cd, const char **strp, + int opindex, signed long *valuep) +{ + const char *errmsg = 0; + signed long value; + + if (strncasecmp (*strp, "%lo16(", 6) == 0) + { + enum cgen_parse_operand_result result_type; + bfd_vma value; + const char *errmsg; + + *strp += 6; + 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; + } + + if (strncasecmp (*strp, "%hi16(", 6) == 0) + { + enum cgen_parse_operand_result result_type; + bfd_vma value; + const char *errmsg; + + *strp += 6; + 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 >>= 16; + } + *valuep = value; + return errmsg; + } + + PARSE_SIGNED; + + if (value <= 65535 && value > 32767) + value -= 0x10000; + + if (value < -32768 || value > 32767) + return _("dsp:16 immediate is out of range"); + + *valuep = value; + return 0; +} + +static const char * +parse_unsigned20 (CGEN_CPU_DESC cd, const char **strp, + int opindex, unsigned long *valuep) +{ + const char *errmsg = 0; + unsigned long value; + + /* Don't successfully parse literals beginning with '['. */ + if (**strp == '[') + return "Invalid literal"; /* Anything -- will not be seen. */ + + /* Don't successfully parse register names. */ + if (m32c_cgen_isa_register (strp)) + return "Invalid literal"; /* Anything -- will not be seen. */ + + errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value); + if (errmsg) + return errmsg; + + if (value > 0xfffff) + return _("dsp:20 immediate is out of range"); + + *valuep = value; + return 0; +} + +static const char * +parse_unsigned24 (CGEN_CPU_DESC cd, const char **strp, + int opindex, unsigned long *valuep) +{ + const char *errmsg = 0; + unsigned long value; + + /* Don't successfully parse literals beginning with '['. */ + if (**strp == '[') + return "Invalid literal"; /* Anything -- will not be seen. */ + + /* Don't successfully parse register names. */ + if (m32c_cgen_isa_register (strp)) + return "Invalid literal"; /* Anything -- will not be seen. */ + + errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value); + if (errmsg) + return errmsg; + + if (value > 0xffffff) + return _("dsp:24 immediate is out of range"); + + *valuep = value; + return 0; +} + +/* This should only be used for #imm->reg. */ +static const char * +parse_signed24 (CGEN_CPU_DESC cd, const char **strp, + int opindex, signed long *valuep) +{ + const char *errmsg = 0; + signed long value; + + PARSE_SIGNED; + + if (value <= 0xffffff && value > 0x7fffff) + value -= 0x1000000; + + if (value > 0xffffff) + return _("dsp:24 immediate is out of range"); + + *valuep = value; + return 0; +} + +static const char * +parse_signed32 (CGEN_CPU_DESC cd, const char **strp, + int opindex, signed long *valuep) +{ + const char *errmsg = 0; + signed long value; + + errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); + if (errmsg) + return errmsg; + + *valuep = value; + return 0; +} + +static const char * +parse_imm1_S (CGEN_CPU_DESC cd, const char **strp, + int opindex, signed long *valuep) +{ + const char *errmsg = 0; + signed long value; + + errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); + if (errmsg) + return errmsg; + + if (value < 1 || value > 2) + return _("immediate is out of range 1-2"); + + *valuep = value; + return 0; +} + +static const char * +parse_imm3_S (CGEN_CPU_DESC cd, const char **strp, + int opindex, signed long *valuep) +{ + const char *errmsg = 0; + signed long value; + + errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); + if (errmsg) + return errmsg; + + if (value < 1 || value > 8) + return _("immediate is out of range 1-8"); + + *valuep = value; + return 0; +} + +static const char * +parse_bit3_S (CGEN_CPU_DESC cd, const char **strp, + int opindex, signed long *valuep) +{ + const char *errmsg = 0; + signed long value; + + errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); + if (errmsg) + return errmsg; + + if (value < 0 || value > 7) + return _("immediate is out of range 0-7"); + + *valuep = value; + return 0; +} + +static const char * +parse_lab_5_3 (CGEN_CPU_DESC cd, + const char **strp, + int opindex ATTRIBUTE_UNUSED, + int opinfo, + enum cgen_parse_operand_result *type_addr, + bfd_vma *valuep) +{ + const char *errmsg = 0; + bfd_vma value; + enum cgen_parse_operand_result op_res; + + errmsg = cgen_parse_address (cd, strp, M32C_OPERAND_LAB_5_3, + opinfo, & op_res, & value); + + if (type_addr) + *type_addr = op_res; + + if (op_res == CGEN_PARSE_OPERAND_RESULT_QUEUED) + { + /* This is a hack; the field cannot handle near-zero signed + offsets that CGEN wants to put in to indicate an "empty" + operand at first. */ + *valuep = 2; + return 0; + } + if (errmsg) + return errmsg; + + if (value < 2 || value > 9) + return _("immediate is out of range 2-9"); + + *valuep = value; + return 0; +} + +static const char * +parse_Bitno16R (CGEN_CPU_DESC cd, const char **strp, + int opindex, unsigned long *valuep) +{ + const char *errmsg = 0; + unsigned long value; + + errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value); + if (errmsg) + return errmsg; + + if (value > 15) + return _("Bit number for indexing general register is out of range 0-15"); + + *valuep = value; + return 0; +} + +static const char * +parse_unsigned_bitbase (CGEN_CPU_DESC cd, const char **strp, + int opindex, unsigned long *valuep, + unsigned bits, int allow_syms) +{ + const char *errmsg = 0; + unsigned long bit; + unsigned long base; + const char *newp = *strp; + unsigned long long bitbase; + long have_zero = 0; + + errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & bit); + if (errmsg) + return errmsg; + + if (*newp != ',') + return "Missing base for bit,base:8"; + + ++newp; + + if (strncmp (newp, "0x0", 3) == 0 + || (newp[0] == '0' && newp[1] != 'x')) + have_zero = 1; + + errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & base); + if (errmsg) + return errmsg; + + bitbase = (unsigned long long) bit + ((unsigned long long) base * 8); + + if (bitbase >= (1ull << bits)) + return _("bit,base is out of range"); + + /* If this field may require a relocation then use larger displacement. */ + if (! have_zero && base == 0) + { + switch (allow_syms) { + case 0: + return _("bit,base out of range for symbol"); + case 1: + break; + case 2: + if (strncmp (newp, "[sb]", 4) != 0) + return _("bit,base out of range for symbol"); + break; + } + } + + *valuep = bitbase; + *strp = newp; + return 0; +} + +static const char * +parse_signed_bitbase (CGEN_CPU_DESC cd, const char **strp, + int opindex, signed long *valuep, + unsigned bits, int allow_syms) +{ + const char *errmsg = 0; + unsigned long bit; + signed long base; + const char *newp = *strp; + long long bitbase; + long long limit; + long have_zero = 0; + + errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & bit); + if (errmsg) + return errmsg; + + if (*newp != ',') + return "Missing base for bit,base:8"; + + ++newp; + + if (strncmp (newp, "0x0", 3) == 0 + || (newp[0] == '0' && newp[1] != 'x')) + have_zero = 1; + + errmsg = cgen_parse_signed_integer (cd, & newp, opindex, & base); + if (errmsg) + return errmsg; + + bitbase = (long long)bit + ((long long)base * 8); + + limit = 1ll << (bits - 1); + if (bitbase < -limit || bitbase >= limit) + return _("bit,base is out of range"); + + /* If this field may require a relocation then use larger displacement. */ + if (! have_zero && base == 0 && ! allow_syms) + return _("bit,base out of range for symbol"); + + *valuep = bitbase; + *strp = newp; + return 0; +} + +static const char * +parse_unsigned_bitbase8 (CGEN_CPU_DESC cd, const char **strp, + int opindex, unsigned long *valuep) +{ + return parse_unsigned_bitbase (cd, strp, opindex, valuep, 8, 0); +} + +static const char * +parse_unsigned_bitbase11 (CGEN_CPU_DESC cd, const char **strp, + int opindex, unsigned long *valuep) +{ + return parse_unsigned_bitbase (cd, strp, opindex, valuep, 11, 0); +} + +static const char * +parse_unsigned_bitbase16 (CGEN_CPU_DESC cd, const char **strp, + int opindex, unsigned long *valuep) +{ + return parse_unsigned_bitbase (cd, strp, opindex, valuep, 16, 1); +} + +static const char * +parse_unsigned_bitbase19 (CGEN_CPU_DESC cd, const char **strp, + int opindex, unsigned long *valuep) +{ + return parse_unsigned_bitbase (cd, strp, opindex, valuep, 19, 2); +} + +static const char * +parse_unsigned_bitbase27 (CGEN_CPU_DESC cd, const char **strp, + int opindex, unsigned long *valuep) +{ + return parse_unsigned_bitbase (cd, strp, opindex, valuep, 27, 1); +} + +static const char * +parse_signed_bitbase8 (CGEN_CPU_DESC cd, const char **strp, + int opindex, signed long *valuep) +{ + return parse_signed_bitbase (cd, strp, opindex, valuep, 8, 1); +} + +static const char * +parse_signed_bitbase11 (CGEN_CPU_DESC cd, const char **strp, + int opindex, signed long *valuep) +{ + return parse_signed_bitbase (cd, strp, opindex, valuep, 11, 0); +} + +static const char * +parse_signed_bitbase19 (CGEN_CPU_DESC cd, const char **strp, + int opindex, signed long *valuep) +{ + return parse_signed_bitbase (cd, strp, opindex, valuep, 19, 1); +} + +/* Parse the suffix as :<char> or as nothing followed by a whitespace. */ + +static const char * +parse_suffix (const char **strp, char suffix) +{ + const char *newp = *strp; + + if (**strp == ':' && TOLOWER (*(*strp + 1)) == suffix) + newp = *strp + 2; + + if (ISSPACE (*newp)) + { + *strp = newp; + return 0; + } + + return "Invalid suffix"; /* Anything -- will not be seen. */ +} + +static const char * +parse_S (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp, + int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED) +{ + return parse_suffix (strp, 's'); +} + +static const char * +parse_G (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp, + int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED) +{ + return parse_suffix (strp, 'g'); +} + +static const char * +parse_Q (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp, + int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED) +{ + return parse_suffix (strp, 'q'); +} + +static const char * +parse_Z (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp, + int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED) +{ + return parse_suffix (strp, 'z'); +} + +/* Parse an empty suffix. Fail if the next char is ':'. */ + +static const char * +parse_X (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp, + int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED) +{ + if (**strp == ':') + return "Unexpected suffix"; + return 0; +} + +static const char * +parse_r0l_r0h (CGEN_CPU_DESC cd, const char **strp, + int opindex ATTRIBUTE_UNUSED, signed long *valuep) +{ + const char *errmsg; + signed long value; + signed long junk; + const char *newp = *strp; + + /* Parse r0[hl]. */ + errmsg = cgen_parse_keyword (cd, & newp, & m32c_cgen_opval_h_r0l_r0h, & value); + if (errmsg) + return errmsg; + + if (*newp != ',') + return _("not a valid r0l/r0h pair"); + ++newp; + + /* Parse the second register in the pair. */ + if (value == 0) /* r0l */ + errmsg = cgen_parse_keyword (cd, & newp, & m32c_cgen_opval_h_r0h, & junk); + else + errmsg = cgen_parse_keyword (cd, & newp, & m32c_cgen_opval_h_r0l, & junk); + if (errmsg) + return errmsg; + + *strp = newp; + *valuep = ! value; + return 0; +} + +/* Accept .b or .w in any case. */ + +static const char * +parse_size (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp, + int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED) +{ + if (**strp == '.' + && (*(*strp + 1) == 'b' || *(*strp + 1) == 'B' + || *(*strp + 1) == 'w' || *(*strp + 1) == 'W')) + { + *strp += 2; + return NULL; + } + + return _("Invalid size specifier"); +} + +/* Special check to ensure that instruction exists for given machine. */ + +int +m32c_cgen_insn_supported (CGEN_CPU_DESC cd, + const CGEN_INSN *insn) +{ + int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH); + CGEN_BITSET isas = CGEN_INSN_BITSET_ATTR_VALUE (insn, CGEN_INSN_ISA); + + /* If attributes are absent, assume no restriction. */ + if (machs == 0) + machs = ~0; + + return ((machs & cd->machs) + && cgen_bitset_intersect_p (& isas, cd->isas)); +} + +/* Parse a set of registers, R0,R1,A0,A1,SB,FB. */ + +static const char * +parse_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + const char **strp, + int opindex ATTRIBUTE_UNUSED, + unsigned long *valuep, + int push) +{ + const char *errmsg = 0; + int regno = 0; + + *valuep = 0; + while (**strp && **strp != ')') + { + if (**strp == 'r' || **strp == 'R') + { + ++*strp; + regno = **strp - '0'; + if (regno > 4) + errmsg = _("Register number is not valid"); + } + else if (**strp == 'a' || **strp == 'A') + { + ++*strp; + regno = **strp - '0'; + if (regno > 2) + errmsg = _("Register number is not valid"); + regno = **strp - '0' + 4; + } + + else if (strncasecmp (*strp, "sb", 2) == 0 || strncasecmp (*strp, "SB", 2) == 0) + { + regno = 6; + ++*strp; + } + + else if (strncasecmp (*strp, "fb", 2) == 0 || strncasecmp (*strp, "FB", 2) == 0) + { + regno = 7; + ++*strp; + } + + if (push) /* Mask is reversed for push. */ + *valuep |= 0x80 >> regno; + else + *valuep |= 1 << regno; + + ++*strp; + if (**strp == ',') + { + if (*(*strp + 1) == ')') + break; + ++*strp; + } + } + + if (!*strp) + errmsg = _("Register list is not valid"); + + return errmsg; +} + +#define POP 0 +#define PUSH 1 + +static const char * +parse_pop_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + const char **strp, + int opindex ATTRIBUTE_UNUSED, + unsigned long *valuep) +{ + return parse_regset (cd, strp, opindex, valuep, POP); +} + +static const char * +parse_push_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + const char **strp, + int opindex ATTRIBUTE_UNUSED, + unsigned long *valuep) +{ + return parse_regset (cd, strp, opindex, valuep, PUSH); +} + +/* -- dis.c */ + +#include "elf/m32c.h" +#include "elf-bfd.h" + +/* Always print the short insn format suffix as ':<char>'. */ + +static void +print_suffix (void * dis_info, char suffix) +{ + disassemble_info *info = dis_info; + + (*info->fprintf_func) (info->stream, ":%c", suffix); +} + +static void +print_S (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value ATTRIBUTE_UNUSED, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + print_suffix (dis_info, 's'); +} + + +static void +print_G (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value ATTRIBUTE_UNUSED, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + print_suffix (dis_info, 'g'); +} + +static void +print_Q (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value ATTRIBUTE_UNUSED, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + print_suffix (dis_info, 'q'); +} + +static void +print_Z (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value ATTRIBUTE_UNUSED, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + print_suffix (dis_info, 'z'); +} + +/* Print the empty suffix. */ + +static void +print_X (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info ATTRIBUTE_UNUSED, + long value ATTRIBUTE_UNUSED, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + return; +} + +static void +print_r0l_r0h (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + disassemble_info *info = dis_info; + + if (value == 0) + (*info->fprintf_func) (info->stream, "r0h,r0l"); + else + (*info->fprintf_func) (info->stream, "r0l,r0h"); +} + +static void +print_unsigned_bitbase (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + unsigned long value, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + disassemble_info *info = dis_info; + + (*info->fprintf_func) (info->stream, "%ld,0x%lx", value & 0x7, value >> 3); +} + +static void +print_signed_bitbase (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + signed long value, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + disassemble_info *info = dis_info; + + (*info->fprintf_func) (info->stream, "%ld,%ld", value & 0x7, value >> 3); +} + +static void +print_size (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value ATTRIBUTE_UNUSED, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + /* Always print the size as '.w'. */ + disassemble_info *info = dis_info; + + (*info->fprintf_func) (info->stream, ".w"); +} + +#define POP 0 +#define PUSH 1 + +static void print_pop_regset (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int); +static void print_push_regset (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int); + +/* Print a set of registers, R0,R1,A0,A1,SB,FB. */ + +static void +print_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED, + int push) +{ + static char * m16c_register_names [] = + { + "r0", "r1", "r2", "r3", "a0", "a1", "sb", "fb" + }; + disassemble_info *info = dis_info; + int mask; + int index = 0; + char* comma = ""; + + if (push) + mask = 0x80; + else + mask = 1; + + if (value & mask) + { + (*info->fprintf_func) (info->stream, "%s", m16c_register_names [0]); + comma = ","; + } + + for (index = 1; index <= 7; ++index) + { + if (push) + mask >>= 1; + else + mask <<= 1; + + if (value & mask) + { + (*info->fprintf_func) (info->stream, "%s%s", comma, + m16c_register_names [index]); + comma = ","; + } + } +} + +static void +print_pop_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + print_regset (cd, dis_info, value, attrs, pc, length, POP); +} + +static void +print_push_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + print_regset (cd, dis_info, value, attrs, pc, length, PUSH); +} + +static void +print_signed4n (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + signed long value, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + disassemble_info *info = dis_info; + + (*info->fprintf_func) (info->stream, "%ld", -value); +} diff --git a/cpu/m32r.cpu b/cpu/m32r.cpu new file mode 100644 index 00000000000..e24fc3d19fc --- /dev/null +++ b/cpu/m32r.cpu @@ -0,0 +1,2427 @@ +; Renesas M32R CPU description. -*- Scheme -*- +; +; Copyright 1998, 1999, 2000, 2001, 2003, 2007, 2009 +; Free Software Foundation, Inc. +; +; Contributed by Red Hat Inc; developed under contract from Mitsubishi +; Electric Corporation. +; +; 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") + +; FIXME: Delete sign extension of accumulator results. +; Sign extension is done when accumulator is read. + +; define-arch must appear first + +(define-arch + (name m32r) ; name of cpu family + (comment "Renesas M32R") + (default-alignment aligned) + (insn-lsb0? #f) + (machs m32r m32rx m32r2) + (isas m32r) +) + +; Attributes. + +; An attribute to describe which pipeline an insn runs in. +; O_OS is a special attribute for sll, sra, sla, slli, srai, slai. +; These instructions have O attribute for m32rx and OS attribute for m32r2. + +(define-attr + (for insn) + (type enum) + (name PIPE) + (comment "parallel execution pipeline selection") + (values NONE O S OS O_OS) +) + +; A derived attribute that says which insns can be executed in parallel +; with others. This is a required attribute for architectures with +; parallel execution. + +(define-attr + (for insn) + (type enum) + (name PARALLEL) + (attrs META) ; do not define in any generated file for now + (values NO YES) + (default (if (eq-attr (current-insn) PIPE NONE) (symbol NO) (symbol YES))) +) + +; Instruction set parameters. + +(define-isa + (name m32r) + + ; This is 32 because 16 bit insns always appear as pairs. + ; ??? See if this can go away. It's only used by the disassembler (right?) + ; to decide how long an unknown insn is. One value isn't sufficient (e.g. if + ; on a 16 bit (and not 32 bit) boundary, will only want to advance pc by 16.) + (default-insn-bitsize 32) + + ; Number of bytes of insn we can initially fetch. + ; The M32R is tricky in that insns are either two 16-bit insns + ; (executed sequentially or in parallel) or one 32-bit insn. + ; So on one hand the base insn size is 16 bits, but on another it's 32. + ; 32 is chosen because: + ; - if the chip were ever bi-endian it is believed that the byte order would + ; be based on 32 bit quantities + ; - 32 bit insns are always aligned on 32 bit boundaries + ; - the pc will never stop on a 16 bit (and not 32 bit) boundary + ; [well actually it can, but there are no branches to such places] + (base-insn-bitsize 32) + + ; Used in computing bit numbers. + (default-insn-word-bitsize 32) + + ; The m32r fetches 2 insns at a time. + (liw-insns 2) + + ; While the m32r can execute insns in parallel, the base mach can't + ; (other than nop). The base mach is greatly handicapped by this, but + ; we still need to cleanly handle it. + (parallel-insns 2) + + ; Initial bitnumbers to decode insns by. + (decode-assist (0 1 2 3 8 9 10 11)) + + ; Classification of instructions that fit in the various frames. + ; wip, not currently used + (insn-types (long ; name + 31 ; length + (eq-attr (current-insn) LENGTH 31) ; matching insns + (0 1 2 7 8 9 10) ; decode-assist + ) + (short + 15 + (eq-attr (current-insn) LENGTH 15) ; matching insns + (0 1 2 7 8 9 10) + ) + ) + + ; Instruction framing. + ; Each m32r insn is either one 32 bit insn, two 16 bit insns executed + ; serially (left->right), or two 16 bit insns executed parallelly. + ; wip, not currently used + (frame long32 ; name + ((long)) ; list of insns in frame, plus constraint + "$0" ; assembler + (+ (1 1) (31 $0)) ; value + (sequence () (execute $0)) ; action + ) + (frame serial2x16 + ((short) + (short)) + "$0 -> $1" + (+ (1 0) (15 $0) (1 0) (15 $1)) + (sequence () + (execute $0) + (execute $1)) + ) + (frame parallel2x16 + ((short (eq-attr (current-insn) PIPE "O,BOTH")) + (short (eq-attr (current-insn) PIPE "S,BOTH"))) + "$0 || $1" + (+ (1 0) (15 $0) (1 1) (15 $1)) + (parallel () + (execute $0) + (execute $1)) + ) +) + +; Cpu family definitions. + +; ??? define-cpu-family [and in general "cpu-family"] might be clearer than +; define-cpu. +; ??? Have define-arch provide defaults for architecture that define-cpu can +; then override [reduces duplication in define-cpu]. +; ??? Another way to go is to delete cpu-families entirely and have one mach +; able to inherit things from another mach (would also need the ability to +; not only override specific inherited things but also disable some, +; e.g. if an insn wasn't supported). + +(define-cpu + ; cpu names must be distinct from the architecture name and machine names. + ; The "b" suffix stands for "base" and is the convention. + ; The "f" suffix stands for "family" and is the convention. + (name m32rbf) + (comment "Renesas M32R base family") + (endian either) + (word-bitsize 32) + ; Override isa spec (??? keeps things simpler, though it was more true + ; in the early days and not so much now). + (parallel-insns 1) +) + +(define-cpu + (name m32rxf) + (comment "Renesas M32Rx family") + (endian either) + (word-bitsize 32) + ; Generated files have an "x" suffix. + (file-transform "x") +) + +(define-cpu + (name m32r2f) + (comment "Renesas M32R2 family") + (endian either) + (word-bitsize 32) + ; Generated files have an "2" suffix. + (file-transform "2") +) + +(define-mach + (name m32r) + (comment "Generic M32R cpu") + (cpu m32rbf) +) + +(define-mach + (name m32rx) + (comment "M32RX cpu") + (cpu m32rxf) +) + +(define-mach + (name m32r2) + (comment "M32R2 cpu") + (cpu m32r2f) +) + +; Model descriptions. + +; The meaning of this value is wip but at the moment it's intended to describe +; the implementation (i.e. what -mtune=foo does in sparc gcc). +; +; Notes while wip: +; - format of pipeline entry: +; (pipeline name (stage1-name ...) (stage2-name ...) ...) +; The contents of a stage description is wip. +; - each mach must have at least one model +; - the default model must be the first one +;- maybe have `retire' support update total cycle count to handle current +; parallel insn cycle counting problems + +(define-model + (name m32r/d) (comment "m32r/d") (attrs) + (mach m32r) + + ;(prefetch) + ;(retire) + + (pipeline p-non-mem "" () ((fetch) (decode) (execute) (writeback))) + (pipeline p-mem "" () ((fetch) (decode) (execute) (memory) (writeback))) + + ; `state' is a list of variables for recording model state + (state + ; bit mask of h-gr registers, =1 means value being loaded from memory + (h-gr UINT) + ) + + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + ((sr INT -1) (dr INT -1)) ; inputs + ((dr INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-cmp "Compare Unit" () + 1 1 ; issue done + () ; state + ((src1 INT -1) (src2 INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + (unit u-mac "Multiply/Accumulate Unit" () + 1 1 ; issue done + () ; state + ((src1 INT -1) (src2 INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + (unit u-cti "Branch Unit" () + 1 1 ; issue done + () ; state + ((sr INT -1)) ; inputs + ((pc)) ; outputs + () ; profile action (default) + ) + (unit u-load "Memory Load Unit" () + 1 1 ; issue done + () ; state + ((sr INT) + ;(ld-mem AI) + ) ; inputs + ((dr INT)) ; outputs + () ; profile action (default) + ) + (unit u-store "Memory Store Unit" () + 1 1 ; issue done + () ; state + ((src1 INT) (src2 INT)) ; inputs + () ; ((st-mem AI)) ; outputs + () ; profile action (default) + ) +) + +(define-model + (name test) (comment "test") (attrs) + (mach m32r) + (pipeline all "" () ((fetch) (decode) (execute) (writeback))) + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () () () ()) +) + +; Each mach must have at least one model. + +(define-model + (name m32rx) (comment "m32rx") (attrs) + (mach m32rx) + + ; ??? It's 6 stages but I forget the details right now. + (pipeline p-o "" () ((fetch) (decode) (execute) (writeback))) + (pipeline p-s "" () ((fetch) (decode) (execute) (writeback))) + (pipeline p-o-mem "" () ((fetch) (decode) (execute) (memory) (writeback))) + + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + ((sr INT -1) (dr INT -1)) ; inputs + ((dr INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-cmp "Compare Unit" () + 1 1 ; issue done + () ; state + ((src1 INT -1) (src2 INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + (unit u-mac "Multiply/Accumulate Unit" () + 1 1 ; issue done + () ; state + ((src1 INT -1) (src2 INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + (unit u-cti "Branch Unit" () + 1 1 ; issue done + () ; state + ((sr INT -1)) ; inputs + ((pc)) ; outputs + () ; profile action (default) + ) + (unit u-load "Memory Load Unit" () + 1 1 ; issue done + () ; state + ((sr INT)) ; inputs + ((dr INT)) ; outputs + () ; profile action (default) + ) + (unit u-store "Memory Store Unit" () + 1 1 ; issue done + () ; state + ((src1 INT) (src2 INT)) ; inputs + () ; outputs + () ; profile action (default) + ) +) + +(define-model + (name m32r2) (comment "m32r2") (attrs) + (mach m32r2) + + ; ??? It's 6 stages but I forget the details right now. + (pipeline p-o "" () ((fetch) (decode) (execute) (writeback))) + (pipeline p-s "" () ((fetch) (decode) (execute) (writeback))) + (pipeline p-o-mem "" () ((fetch) (decode) (execute) (memory) (writeback))) + + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + ((sr INT -1) (dr INT -1)) ; inputs + ((dr INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-cmp "Compare Unit" () + 1 1 ; issue done + () ; state + ((src1 INT -1) (src2 INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + (unit u-mac "Multiply/Accumulate Unit" () + 1 1 ; issue done + () ; state + ((src1 INT -1) (src2 INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + (unit u-cti "Branch Unit" () + 1 1 ; issue done + () ; state + ((sr INT -1)) ; inputs + ((pc)) ; outputs + () ; profile action (default) + ) + (unit u-load "Memory Load Unit" () + 1 1 ; issue done + () ; state + ((sr INT)) ; inputs + ((dr INT)) ; outputs + () ; profile action (default) + ) + (unit u-store "Memory Store Unit" () + 1 1 ; issue done + () ; state + ((src1 INT) (src2 INT)) ; inputs + () ; outputs + () ; profile action (default) + ) +) + +; The instruction fetch/execute cycle. +; This is split into two parts as sometimes more than one instruction is +; decoded at once. +; The `const SI' argument to decode/execute is used to distinguish +; multiple instructions processed at the same time (e.g. m32r). +; +; ??? This is wip, and not currently used. +; ??? Needs to be moved to define-isa. + +; This is how to fetch and decode an instruction. + +;(define-extract +; (sequence VOID +; (if VOID (ne AI (and AI pc (const AI 3)) (const AI 0)) +; (sequence VOID +; (set-quiet USI (scratch UHI insn1) (ifetch UHI pc)) +; (decode VOID pc (and UHI insn1 (const UHI #x7fff)) +; (const SI 0))) +; (sequence VOID +; (set-quiet USI (scratch USI insn) (ifetch USI pc)) +; (if VOID (ne USI (and USI insn (const USI #x80000000)) +; (const USI 0)) +; (decode VOID pc (srl USI insn (const WI 16)) (const SI 0)) +; (sequence VOID +; ; ??? parallel support +; (decode VOID pc (srl USI insn (const WI 16)) +; (const SI 0)) +; (decode VOID (add AI pc (const AI 2)) +; (and USI insn (const WI #x7fff)) +; (const SI 1)))))) +; ) +;) + +; This is how to execute a decoded instruction. + +;(define-execute +; (sequence VOID () ; () is empty option list +; ((AI new_pc)) +; (set AI new_pc (execute: AI (const 0)) #:quiet) +; (set AI pc new_pc #:direct) +; ) +;) + +; FIXME: It might simplify things to separate the execute process from the +; one that updates the PC. + +; Instruction fields. +; +; Attributes: +; PCREL-ADDR: pc relative value (for reloc and disassembly purposes) +; ABS-ADDR: absolute address (for reloc and disassembly purposes?) +; RESERVED: bits are not used to decode insn, must be all 0 +; RELOC: there is a relocation associated with this field (experiment) + +(define-attr + (for ifield operand) + (type boolean) + (name RELOC) + (comment "there is a reloc associated with this field (experiment)") +) + +(dnf f-op1 "op1" () 0 4) +(dnf f-op2 "op2" () 8 4) +(dnf f-cond "cond" () 4 4) +(dnf f-r1 "r1" () 4 4) +(dnf f-r2 "r2" () 12 4) +(df f-simm8 "simm8" () 8 8 INT #f #f) +(df f-simm16 "simm16" () 16 16 INT #f #f) +(dnf f-shift-op2 "shift op2" () 8 3) +(dnf f-uimm3 "uimm3" () 5 3) +(dnf f-uimm4 "uimm4" () 12 4) +(dnf f-uimm5 "uimm5" () 11 5) +(dnf f-uimm8 "uimm8" () 8 8) +(dnf f-uimm16 "uimm16" () 16 16) +(dnf f-uimm24 "uimm24" (ABS-ADDR RELOC) 8 24) +(dnf f-hi16 "high 16 bits" (SIGN-OPT) 16 16) +(df f-disp8 "disp8, slot unknown" (PCREL-ADDR RELOC) 8 8 INT + ((value pc) (sra WI (sub WI value (and WI pc (const -4))) (const 2))) + ((value pc) (add WI (sll WI value (const 2)) (and WI pc (const -4))))) +(df f-disp16 "disp16" (PCREL-ADDR RELOC) 16 16 INT + ((value pc) (sra WI (sub WI value pc) (const 2))) + ((value pc) (add WI (sll WI value (const 2)) pc))) +(df f-disp24 "disp24" (PCREL-ADDR RELOC) 8 24 INT + ((value pc) (sra WI (sub WI value pc) (const 2))) + ((value pc) (add WI (sll WI value (const 2)) pc))) + +(dnf f-op23 "op2.3" () 9 3) +(dnf f-op3 "op3" () 14 2) +(dnf f-acc "acc" () 8 1) +(dnf f-accs "accs" () 12 2) +(dnf f-accd "accd" () 4 2) +(dnf f-bits67 "bits67" () 6 2) +(dnf f-bit4 "bit4" () 4 1) +(dnf f-bit14 "bit14" () 14 1) + +(define-ifield (name f-imm1) (comment "1 bit immediate, 0->1 1->2") + (attrs) + (start 15) (length 1) + (encode (value pc) (sub WI value (const WI 1))) + (decode (value pc) (add WI value (const WI 1))) +) + +; Enums. + +; insn-op1: bits 0-3 +; FIXME: should use die macro or some such +(define-normal-insn-enum insn-op1 "insn format enums" () OP1_ f-op1 + ("0" "1" "2" "3" "4" "5" "6" "7" + "8" "9" "10" "11" "12" "13" "14" "15") +) + +; insn-op2: bits 8-11 +; FIXME: should use die macro or some such +(define-normal-insn-enum insn-op2 "op2 enums" () OP2_ f-op2 + ("0" "1" "2" "3" "4" "5" "6" "7" + "8" "9" "10" "11" "12" "13" "14" "15") +) + +; Hardware pieces. +; These entries list the elements of the raw hardware. +; They're also used to provide tables and other elements of the assembly +; language. + +(dnh h-pc "program counter" (PC PROFILE) (pc) () () ()) + +(dnh h-hi16 "high 16 bits" () + (immediate (UINT 16)) + () () () +) + +; These two aren't technically needed. +; They're here for illustration sake mostly. +; Plus they cause the value to be stored in the extraction buffers to only +; be 16 bits wide (vs 32 or 64). Whoopie ding. But it's fun. +(dnh h-slo16 "signed low 16 bits" () + (immediate (INT 16)) + () () () +) +(dnh h-ulo16 "unsigned low 16 bits" () + (immediate (UINT 16)) + () () () +) + +(define-keyword + (name gr-names) + (print-name h-gr) + (prefix "") + (values (fp 13) (lr 14) (sp 15) + (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)) +) + +(define-hardware + (name h-gr) + (comment "general registers") + (attrs PROFILE CACHE-ADDR) + (type register WI (16)) + (indices extern-keyword gr-names) +) + +(define-keyword + (name cr-names) + (print-name h-cr) + (prefix "") + (values (psw 0) (cbr 1) (spi 2) (spu 3) + (bpc 6) (bbpsw 8) (bbpc 14) (evb 5) + (cr0 0) (cr1 1) (cr2 2) (cr3 3) + (cr4 4) (cr5 5) (cr6 6) (cr7 7) + (cr8 8) (cr9 9) (cr10 10) (cr11 11) + (cr12 12) (cr13 13) (cr14 14) (cr15 15)) +) + +(define-hardware + (name h-cr) + (comment "control registers") + (type register UWI (16)) + (indices extern-keyword cr-names) + (get (index) (c-call UWI "@cpu@_h_cr_get_handler" index)) + (set (index newval) (c-call VOID "@cpu@_h_cr_set_handler" index newval)) +) + +; The actual accumulator is only 56 bits. +; The top 8 bits are sign extended from bit 8 (when counting msb = bit 0). +; To simplify the accumulator instructions, no attempt is made to keep the +; top 8 bits properly sign extended (currently there's no point since they +; all ignore them). When the value is read it is properly sign extended +; [in the `get' handler]. +(define-hardware + (name h-accum) + (comment "accumulator") + (type register DI) + (get () (c-call DI "@cpu@_h_accum_get_handler")) + (set (newval) (c-call VOID "@cpu@_h_accum_set_handler" newval)) +) + +; FIXME: Revisit after sanitization can be removed. Remove h-accum. +(define-hardware + (name h-accums) + (comment "accumulators") + (attrs (MACH m32rx,m32r2)) + (type register DI (2)) + (indices keyword "" ((a0 0) (a1 1))) + ; get/set so a0 accesses are redirected to h-accum. + ; They're also so reads can properly sign extend the value. + ; FIXME: Needn't be a function call. + (get (index) (c-call DI "@cpu@_h_accums_get_handler" index)) + (set (index newval) (c-call VOID "@cpu@_h_accums_set_handler" index newval)) +) + +; For condbit operand. FIXME: Need to allow spec of get/set of operands. +; Having this separate from h-psw keeps the parts that use it simpler +; [since they greatly outnumber those that use h-psw]. +(dsh h-cond "condition bit" () (register BI)) + +; The actual values of psw,bpsw,bbpsw are recorded here to allow access +; to them as a unit. +(define-hardware + (name h-psw) + (comment "psw part of psw") + (type register UQI) + ; get/set to handle cond bit. + ; FIXME: missing: use's and clobber's + ; FIXME: remove c-call? + (get () (c-call UQI "@cpu@_h_psw_get_handler")) + (set (newval) (c-call VOID "@cpu@_h_psw_set_handler" newval)) +) +(dsh h-bpsw "backup psw" () (register UQI)) +(dsh h-bbpsw "backup bpsw" () (register UQI)) + +; FIXME: Later make add get/set specs and support SMP. +(dsh h-lock "lock" () (register BI)) + +; Instruction Operands. +; These entries provide a layer between the assembler and the raw hardware +; description, and are used to refer to hardware elements in the semantic +; code. Usually there's a bit of over-specification, but in more complicated +; instruction sets there isn't. + +; M32R specific operand attributes: + +(define-attr + (for operand) + (type boolean) + (name HASH-PREFIX) + (comment "immediates have an optional '#' prefix") +) + +; ??? Convention says this should be o-sr, but then the insn definitions +; should refer to o-sr which is clumsy. The "o-" could be implicit, but +; then it should be implicit for all the symbols here, but then there would +; be confusion between (f-)simm8 and (h-)simm8. +; So for now the rule is exactly as it appears here. + +(dnop sr "source register" () h-gr f-r2) +(dnop dr "destination register" () h-gr f-r1) +;; The assembler relies upon the fact that dr and src1 are the same field. +;; FIXME: Revisit. +(dnop src1 "source register 1" () h-gr f-r1) +(dnop src2 "source register 2" () h-gr f-r2) +(dnop scr "source control register" () h-cr f-r2) +(dnop dcr "destination control register" () h-cr f-r1) + +(dnop simm8 "8 bit signed immediate" (HASH-PREFIX) h-sint f-simm8) +(dnop simm16 "16 bit signed immediate" (HASH-PREFIX) h-sint f-simm16) +(dnop uimm3 "3 bit unsigned number" (HASH-PREFIX) h-uint f-uimm3) +(dnop uimm4 "4 bit trap number" (HASH-PREFIX) h-uint f-uimm4) +(dnop uimm5 "5 bit shift count" (HASH-PREFIX) h-uint f-uimm5) +(dnop uimm8 "8 bit unsigned immediate" (HASH-PREFIX) h-uint f-uimm8) +(dnop uimm16 "16 bit unsigned immediate" (HASH-PREFIX) h-uint f-uimm16) + +(dnop imm1 "1 bit immediate" ((MACH m32rx,m32r2) HASH-PREFIX) h-uint f-imm1) +(dnop accd "accumulator destination register" ((MACH m32rx,m32r2)) h-accums f-accd) +(dnop accs "accumulator source register" ((MACH m32rx,m32r2)) h-accums f-accs) +(dnop acc "accumulator reg (d)" ((MACH m32rx,m32r2)) h-accums f-acc) + +; slo16,ulo16 are used in both with-hash-prefix/no-hash-prefix cases. +; e.g. add3 r3,r3,#1 and ld r3,@(4,r4). We could use HASH-PREFIX. +; Instead we create a fake operand `hash'. The m32r is an illustration port, +; so we often try out various ways of doing things. + +(define-operand (name hash) (comment "# prefix") (attrs) + (type h-sint) ; doesn't really matter + (index f-nil) + (handlers (parse "hash") (print "hash")) +) + +; For high(foo),shigh(foo). +(define-operand + (name hi16) + (comment "high 16 bit immediate, sign optional") + (attrs) + (type h-hi16) + (index f-hi16) + (handlers (parse "hi16")) +) + +; For low(foo),sda(foo). +(define-operand + (name slo16) + (comment "16 bit signed immediate, for low()") + (attrs) + (type h-slo16) + (index f-simm16) + (handlers (parse "slo16")) +) + +; For low(foo). +(define-operand + (name ulo16) + (comment "16 bit unsigned immediate, for low()") + (attrs) + (type h-ulo16) + (index f-uimm16) + (handlers (parse "ulo16")) +) + +(dnop uimm24 "24 bit address" (HASH-PREFIX) h-addr f-uimm24) + +(define-operand + (name disp8) + (comment "8 bit displacement") + (attrs RELAX) + (type h-iaddr) + (index f-disp8) + ; ??? Early experiments had insert/extract fields here. + ; Moving these to f-disp8 made things cleaner, but may wish to re-introduce + ; fields here to handle more complicated cases. +) + +(dnop disp16 "16 bit displacement" () h-iaddr f-disp16) +(dnop disp24 "24 bit displacement" (RELAX) h-iaddr f-disp24) + +; These hardware elements are refered to frequently. + +(dnop condbit "condition bit" (SEM-ONLY) h-cond f-nil) +(dnop accum "accumulator" (SEM-ONLY) h-accum f-nil) + +; Instruction definitions. +; +; Notes while wip: +; - dni is a cover macro to the real "this is an instruction" keyword. +; The syntax of the real one is yet to be determined. +; At the lowest level (i.e. the "real" one) it will probably take a variable +; list of arguments where each argument [perhaps after the standard three of +; name, comment, attrs] is "(keyword arg-to-keyword)". This syntax is simple +; and yet completely upward extensible. And given the macro facility, one +; needn't code at that low a level so even though it'll be more verbose than +; necessary it won't matter. This same reasoning can be applied to most +; types of entries in this file. + +; M32R specific instruction attributes: + +; FILL-SLOT: Need next insn to begin on 32 bit boundary. +; (A "slot" as used here is a 32 bit quantity that can either be filled with +; one 32 bit insn or two 16 bit insns which go in the "left bin" and "right +; bin" where the left bin is the one with a lower address). + +(define-attr + (for insn) + (type boolean) + (name FILL-SLOT) + (comment "fill right bin with `nop' if insn is in left bin") +) + +(define-attr + (for insn) + (type boolean) + (name SPECIAL) + (comment "non-public m32rx insn") +) + +(define-attr + (for insn) + (type boolean) + (name SPECIAL_M32R) + (comment "non-public m32r insn") +) + +(define-attr + (for insn) + (type boolean) + (name SPECIAL_FLOAT) + (comment "floating point insn") +) + +; IDOC attribute for instruction documentation. + +(define-attr + (for insn) + (type enum) + (name IDOC) + (comment "insn kind for documentation") + (attrs META) + (values + (MEM - () "Memory") + (ALU - () "ALU") + (BR - () "Branch") + (ACCUM - () "Accumulator") + (MAC - () "Multiply/Accumulate") + (MISC - () "Miscellaneous") + ) +) + +(define-pmacro (bin-op mnemonic op2-op sem-op imm-prefix imm) + (begin + (dni mnemonic + (.str mnemonic " reg/reg") + ((PIPE OS) (IDOC ALU)) + (.str mnemonic " $dr,$sr") + (+ OP1_0 op2-op dr sr) + (set dr (sem-op dr sr)) + () + ) + (dni (.sym mnemonic "3") + (.str mnemonic " reg/" imm) + ((IDOC ALU)) + (.str mnemonic "3 $dr,$sr," imm-prefix "$" imm) + (+ OP1_8 op2-op dr sr imm) + (set dr (sem-op sr imm)) + () + ) + ) +) +(bin-op add OP2_10 add "$hash" slo16) +; sub isn't present because sub3 doesn't exist. +(bin-op and OP2_12 and "" uimm16) +(bin-op or OP2_14 or "$hash" ulo16) +(bin-op xor OP2_13 xor "" uimm16) + +(dni addi "addi" + ((PIPE OS) (IDOC ALU)) + ;#.(string-append "addi " "$dr,$simm8") ; #. experiment + "addi $dr,$simm8" + (+ OP1_4 dr simm8) + (set dr (add dr simm8)) + ((m32r/d (unit u-exec)) + (m32rx (unit u-exec)) + (m32r2 (unit u-exec))) +) + +(dni addv "addv" + ((PIPE OS) (IDOC ALU)) + "addv $dr,$sr" + (+ OP1_0 OP2_8 dr sr) + (parallel () + (set dr (add dr sr)) + (set condbit (add-oflag dr sr (const 0)))) + () +) + +(dni addv3 "addv3" + ((IDOC ALU)) + "addv3 $dr,$sr,$simm16" + (+ OP1_8 OP2_8 dr sr simm16) + (parallel () + (set dr (add sr simm16)) + (set condbit (add-oflag sr simm16 (const 0)))) + () +) + +(dni addx "addx" + ((PIPE OS) (IDOC ALU)) + "addx $dr,$sr" + (+ OP1_0 OP2_9 dr sr) + (parallel () + (set dr (addc dr sr condbit)) + (set condbit (add-cflag dr sr condbit))) + () +) + +(dni bc8 "bc with 8 bit displacement" + (COND-CTI (PIPE O) (IDOC BR)) + "bc.s $disp8" + (+ OP1_7 (f-r1 12) disp8) + (if condbit (set pc disp8)) + ((m32r/d (unit u-cti)) + (m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(dnmi bc8r "relaxable bc8" + (COND-CTI RELAXABLE (PIPE O) (IDOC BR)) + "bc $disp8" + (emit bc8 disp8) +) + +(dni bc24 "bc with 24 bit displacement" + (COND-CTI (IDOC BR)) + "bc.l $disp24" + (+ OP1_15 (f-r1 12) disp24) + (if condbit (set pc disp24)) + ((m32r/d (unit u-cti)) + (m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(dnmi bc24r "relaxable bc24" + (COND-CTI RELAXED (IDOC BR)) + "bc $disp24" + (emit bc24 disp24) +) + +(dni beq "beq" + (COND-CTI (IDOC BR)) + "beq $src1,$src2,$disp16" + (+ OP1_11 OP2_0 src1 src2 disp16) + (if (eq src1 src2) (set pc disp16)) + ((m32r/d (unit u-cti) (unit u-cmp (cycles 0))) + (m32rx (unit u-cti) (unit u-cmp (cycles 0))) + (m32r2 (unit u-cti) (unit u-cmp (cycles 0)))) +) + +(define-pmacro (cbranch sym comment op2-op comp-op) + (dni sym comment (COND-CTI (IDOC BR)) + (.str sym " $src2,$disp16") + (+ OP1_11 op2-op (f-r1 0) src2 disp16) + (if (comp-op src2 (const WI 0)) (set pc disp16)) + ((m32r/d (unit u-cti) (unit u-cmp (cycles 0))) + (m32rx (unit u-cti) (unit u-cmp (cycles 0))) + (m32r2 (unit u-cti) (unit u-cmp (cycles 0)))) + ) +) +(cbranch beqz "beqz" OP2_8 eq) +(cbranch bgez "bgez" OP2_11 ge) +(cbranch bgtz "bgtz" OP2_13 gt) +(cbranch blez "blez" OP2_12 le) +(cbranch bltz "bltz" OP2_10 lt) +(cbranch bnez "bnez" OP2_9 ne) + +(dni bl8 "bl with 8 bit displacement" + (UNCOND-CTI FILL-SLOT (PIPE O) (IDOC BR)) + "bl.s $disp8" + (+ OP1_7 (f-r1 14) disp8) + (sequence () + (set (reg h-gr 14) + (add (and pc (const -4)) (const 4))) + (set pc disp8)) + ((m32r/d (unit u-cti)) + (m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(dnmi bl8r "relaxable bl8" + (UNCOND-CTI FILL-SLOT RELAXABLE (PIPE O) (IDOC BR)) + "bl $disp8" + (emit bl8 disp8) +) + +(dni bl24 "bl with 24 bit displacement" + (UNCOND-CTI (IDOC BR)) + "bl.l $disp24" + (+ OP1_15 (f-r1 14) disp24) + (sequence () + (set (reg h-gr 14) (add pc (const 4))) + (set pc disp24)) + ((m32r/d (unit u-cti)) + (m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(dnmi bl24r "relaxable bl24" + (UNCOND-CTI RELAXED (IDOC BR)) + "bl $disp24" + (emit bl24 disp24) +) + +(dni bcl8 "bcl with 8 bit displacement" + (COND-CTI FILL-SLOT (MACH m32rx,m32r2) (PIPE O) (IDOC BR)) + "bcl.s $disp8" + (+ OP1_7 (f-r1 8) disp8) + (if condbit + (sequence () + (set (reg h-gr 14) + (add (and pc (const -4)) + (const 4))) + (set pc disp8))) + ((m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(dnmi bcl8r "relaxable bcl8" + (COND-CTI FILL-SLOT (MACH m32rx,m32r2) (PIPE O) RELAXABLE (IDOC BR)) + "bcl $disp8" + (emit bcl8 disp8) +) + +(dni bcl24 "bcl with 24 bit displacement" + (COND-CTI (MACH m32rx,m32r2) (IDOC BR)) + "bcl.l $disp24" + (+ OP1_15 (f-r1 8) disp24) + (if condbit + (sequence () + (set (reg h-gr 14) (add pc (const 4))) + (set pc disp24))) + ((m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(dnmi bcl24r "relaxable bcl24" + (COND-CTI (MACH m32rx,m32r2) RELAXED (IDOC BR)) + "bcl $disp24" + (emit bcl24 disp24) +) + +(dni bnc8 "bnc with 8 bit displacement" + (COND-CTI (PIPE O) (IDOC BR)) + "bnc.s $disp8" + (+ OP1_7 (f-r1 13) disp8) + (if (not condbit) (set pc disp8)) + ((m32r/d (unit u-cti)) + (m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(dnmi bnc8r "relaxable bnc8" + (COND-CTI RELAXABLE (PIPE O) (IDOC BR)) + "bnc $disp8" + (emit bnc8 disp8) +) + +(dni bnc24 "bnc with 24 bit displacement" + (COND-CTI (IDOC BR)) + "bnc.l $disp24" + (+ OP1_15 (f-r1 13) disp24) + (if (not condbit) (set pc disp24)) + ((m32r/d (unit u-cti)) + (m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(dnmi bnc24r "relaxable bnc24" + (COND-CTI RELAXED (IDOC BR)) + "bnc $disp24" + (emit bnc24 disp24) +) + +(dni bne "bne" + (COND-CTI (IDOC BR)) + "bne $src1,$src2,$disp16" + (+ OP1_11 OP2_1 src1 src2 disp16) + (if (ne src1 src2) (set pc disp16)) + ((m32r/d (unit u-cti) (unit u-cmp (cycles 0))) + (m32rx (unit u-cti) (unit u-cmp (cycles 0))) + (m32r2 (unit u-cti) (unit u-cmp (cycles 0)))) +) + +(dni bra8 "bra with 8 bit displacement" + (UNCOND-CTI FILL-SLOT (PIPE O) (IDOC BR)) + "bra.s $disp8" + (+ OP1_7 (f-r1 15) disp8) + (set pc disp8) + ((m32r/d (unit u-cti)) + (m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(dnmi bra8r "relaxable bra8" + (UNCOND-CTI FILL-SLOT RELAXABLE (PIPE O) (IDOC BR)) + "bra $disp8" + (emit bra8 disp8) +) + +(dni bra24 "bra with 24 displacement" + (UNCOND-CTI (IDOC BR)) + "bra.l $disp24" + (+ OP1_15 (f-r1 15) disp24) + (set pc disp24) + ((m32r/d (unit u-cti)) + (m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(dnmi bra24r "relaxable bra24" + (UNCOND-CTI RELAXED (IDOC BR)) + "bra $disp24" + (emit bra24 disp24) +) + +(dni bncl8 "bncl with 8 bit displacement" + (COND-CTI FILL-SLOT (MACH m32rx,m32r2) (PIPE O) (IDOC BR)) + "bncl.s $disp8" + (+ OP1_7 (f-r1 9) disp8) + (if (not condbit) + (sequence () + (set (reg h-gr 14) + (add (and pc (const -4)) + (const 4))) + (set pc disp8))) + ((m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(dnmi bncl8r "relaxable bncl8" + (COND-CTI FILL-SLOT (MACH m32rx,m32r2) (PIPE O) RELAXABLE (IDOC BR)) + "bncl $disp8" + (emit bncl8 disp8) +) + +(dni bncl24 "bncl with 24 bit displacement" + (COND-CTI (MACH m32rx,m32r2) (IDOC BR)) + "bncl.l $disp24" + (+ OP1_15 (f-r1 9) disp24) + (if (not condbit) + (sequence () + (set (reg h-gr 14) (add pc (const 4))) + (set pc disp24))) + ((m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(dnmi bncl24r "relaxable bncl24" + (COND-CTI (MACH m32rx,m32r2) RELAXED (IDOC BR)) + "bncl $disp24" + (emit bncl24 disp24) +) + +(dni cmp "cmp" + ((PIPE OS) (IDOC ALU)) + "cmp $src1,$src2" + (+ OP1_0 OP2_4 src1 src2) + (set condbit (lt src1 src2)) + ((m32r/d (unit u-cmp)) + (m32rx (unit u-cmp)) + (m32r2 (unit u-cmp))) +) + +(dni cmpi "cmpi" + ((IDOC ALU)) + "cmpi $src2,$simm16" + (+ OP1_8 (f-r1 0) OP2_4 src2 simm16) + (set condbit (lt src2 simm16)) + ((m32r/d (unit u-cmp)) + (m32rx (unit u-cmp)) + (m32r2 (unit u-cmp))) +) + +(dni cmpu "cmpu" + ((PIPE OS) (IDOC ALU)) + "cmpu $src1,$src2" + (+ OP1_0 OP2_5 src1 src2) + (set condbit (ltu src1 src2)) + ((m32r/d (unit u-cmp)) + (m32rx (unit u-cmp)) + (m32r2 (unit u-cmp))) +) + +(dni cmpui "cmpui" + ((IDOC ALU)) + "cmpui $src2,$simm16" + (+ OP1_8 (f-r1 0) OP2_5 src2 simm16) + (set condbit (ltu src2 simm16)) + ((m32r/d (unit u-cmp)) + (m32rx (unit u-cmp)) + (m32r2 (unit u-cmp))) +) + +(dni cmpeq "cmpeq" + ((MACH m32rx,m32r2) (PIPE OS) (IDOC ALU)) + "cmpeq $src1,$src2" + (+ OP1_0 OP2_6 src1 src2) + (set condbit (eq src1 src2)) + ((m32rx (unit u-cmp)) + (m32r2 (unit u-cmp))) +) + +(dni cmpz "cmpz" + ((MACH m32rx,m32r2) (PIPE OS) (IDOC ALU)) + "cmpz $src2" + (+ OP1_0 OP2_7 (f-r1 0) src2) + (set condbit (eq src2 (const 0))) + ((m32rx (unit u-cmp)) + (m32r2 (unit u-cmp))) +) + +(dni div "div" + ((IDOC ALU)) + "div $dr,$sr" + (+ OP1_9 OP2_0 dr sr (f-simm16 0)) + (if (ne sr (const 0)) (set dr (div dr sr))) + ((m32r/d (unit u-exec (cycles 37))) + (m32rx (unit u-exec (cycles 37))) + (m32r2 (unit u-exec (cycles 37)))) +) + +(dni divu "divu" + ((IDOC ALU)) + "divu $dr,$sr" + (+ OP1_9 OP2_1 dr sr (f-simm16 0)) + (if (ne sr (const 0)) (set dr (udiv dr sr))) + ((m32r/d (unit u-exec (cycles 37))) + (m32rx (unit u-exec (cycles 37))) + (m32r2 (unit u-exec (cycles 37)))) +) + +(dni rem "rem" + ((IDOC ALU)) + "rem $dr,$sr" + (+ OP1_9 OP2_2 dr sr (f-simm16 0)) + ; FIXME: Check rounding direction. + (if (ne sr (const 0)) (set dr (mod dr sr))) + ((m32r/d (unit u-exec (cycles 37))) + (m32rx (unit u-exec (cycles 37))) + (m32r2 (unit u-exec (cycles 37)))) +) + +(dni remu "remu" + ((IDOC ALU)) + "remu $dr,$sr" + (+ OP1_9 OP2_3 dr sr (f-simm16 0)) + ; FIXME: Check rounding direction. + (if (ne sr (const 0)) (set dr (umod dr sr))) + ((m32r/d (unit u-exec (cycles 37))) + (m32rx (unit u-exec (cycles 37))) + (m32r2 (unit u-exec (cycles 37)))) +) + +(dni remh "remh" + ((MACH m32r2)) + "remh $dr,$sr" + (+ OP1_9 OP2_2 dr sr (f-simm16 #x10)) + ; FIXME: Check rounding direction. + (if (ne sr (const 0)) (set dr (mod (ext WI (trunc HI dr)) sr))) + ((m32r2 (unit u-exec (cycles 21)))) +) + +(dni remuh "remuh" + ((MACH m32r2)) + "remuh $dr,$sr" + (+ OP1_9 OP2_3 dr sr (f-simm16 #x10)) + ; FIXME: Check rounding direction. + (if (ne sr (const 0)) (set dr (umod dr sr))) + ((m32r2 (unit u-exec (cycles 21)))) +) + +(dni remb "remb" + ((MACH m32r2)) + "remb $dr,$sr" + (+ OP1_9 OP2_2 dr sr (f-simm16 #x18)) + ; FIXME: Check rounding direction. + (if (ne sr (const 0)) (set dr (mod (ext WI (trunc BI dr)) sr))) + ((m32r2 (unit u-exec (cycles 21)))) +) + +(dni remub "remub" + ((MACH m32r2)) + "remub $dr,$sr" + (+ OP1_9 OP2_3 dr sr (f-simm16 #x18)) + ; FIXME: Check rounding direction. + (if (ne sr (const 0)) (set dr (umod dr sr))) + ((m32r2 (unit u-exec (cycles 21)))) +) + +(dni divuh "divuh" + ((MACH m32r2)) + "divuh $dr,$sr" + (+ OP1_9 OP2_1 dr sr (f-simm16 #x10)) + (if (ne sr (const 0)) (set dr (udiv dr sr))) + ((m32r2 (unit u-exec (cycles 21)))) +) + +(dni divb "divb" + ((MACH m32r2)) + "divb $dr,$sr" + (+ OP1_9 OP2_0 dr sr (f-simm16 #x18)) + (if (ne sr (const 0)) (set dr (div (ext WI (trunc BI dr)) sr))) + ((m32r2 (unit u-exec (cycles 21)))) +) + +(dni divub "divub" + ((MACH m32r2)) + "divub $dr,$sr" + (+ OP1_9 OP2_1 dr sr (f-simm16 #x18)) + (if (ne sr (const 0)) (set dr (udiv dr sr))) + ((m32r2 (unit u-exec (cycles 21)))) +) + +(dni divh "divh" + ((MACH m32rx,m32r2) (IDOC ALU)) + "divh $dr,$sr" + (+ OP1_9 OP2_0 dr sr (f-simm16 #x10)) + (if (ne sr (const 0)) (set dr (div (ext WI (trunc HI dr)) sr))) + ((m32rx (unit u-exec (cycles 21))) + (m32r2 (unit u-exec (cycles 21)))) +) + +(dni jc "jc" + (COND-CTI (MACH m32rx,m32r2) (PIPE O) SPECIAL (IDOC BR)) + "jc $sr" + (+ OP1_1 (f-r1 12) OP2_12 sr) + (if condbit (set pc (and sr (const -4)))) + ((m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(dni jnc "jnc" + (COND-CTI (MACH m32rx,m32r2) (PIPE O) SPECIAL (IDOC BR)) + "jnc $sr" + (+ OP1_1 (f-r1 13) OP2_12 sr) + (if (not condbit) (set pc (and sr (const -4)))) + ((m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(dni jl "jl" + (UNCOND-CTI FILL-SLOT (PIPE O) (IDOC BR)) + "jl $sr" + (+ OP1_1 (f-r1 14) OP2_12 sr) + (parallel () + (set (reg h-gr 14) + (add (and pc (const -4)) (const 4))) + (set pc (and sr (const -4)))) + ((m32r/d (unit u-cti)) + (m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(dni jmp "jmp" + (UNCOND-CTI (PIPE O) (IDOC BR)) + "jmp $sr" + (+ OP1_1 (f-r1 15) OP2_12 sr) + (set pc (and sr (const -4))) + ; The above works now so this kludge has been commented out. + ; It's kept around because the f-r1 reference in the semantic part + ; should work. + ; FIXME: kludge, instruction decoding not finished. + ; But this should work, so that's another FIXME. + ;(sequence VOID (if VOID (eq SI f-r1 (const SI 14)) + ; FIXME: abuf->insn should be a macro of some sort. + ;(sequence VOID + ; (if VOID (eq SI (c-code SI "((abuf->insn >> 8) & 15)") + ; (const SI 14)) + ; (set WI (reg WI h-gr 14) + ; (add WI (and WI pc (const WI -4)) (const WI 4)))) + ; (set WI pc sr)) + ((m32r/d (unit u-cti)) + (m32rx (unit u-cti)) + (m32r2 (unit u-cti))) +) + +(define-pmacro (no-ext-expr mode expr) expr) +(define-pmacro (ext-expr mode expr) (ext mode expr)) +(define-pmacro (zext-expr mode expr) (zext mode expr)) + +(define-pmacro (load-op suffix op2-op mode ext-op) + (begin + (dni (.sym ld suffix) (.str "ld" suffix) + ((PIPE O) (IDOC MEM)) + (.str "ld" suffix " $dr,@$sr") + (+ OP1_2 op2-op dr sr) + (set dr (ext-op WI (mem mode sr))) + ((m32r/d (unit u-load)) + (m32rx (unit u-load)) + (m32r2 (unit u-load))) + ) + (dnmi (.sym ld suffix "-2") (.str "ld" suffix "-2") + (NO-DIS (PIPE O) (IDOC MEM)) + (.str "ld" suffix " $dr,@($sr)") + (emit (.sym ld suffix) dr sr)) + (dni (.sym ld suffix -d) (.str "ld" suffix "-d") + ((IDOC MEM)) + (.str "ld" suffix " $dr,@($slo16,$sr)") + (+ OP1_10 op2-op dr sr slo16) + (set dr (ext-op WI (mem mode (add sr slo16)))) + ((m32r/d (unit u-load (cycles 2))) + (m32rx (unit u-load (cycles 2))) + (m32r2 (unit u-load (cycles 2)))) + ) + (dnmi (.sym ld suffix -d2) (.str "ld" suffix "-d2") + (NO-DIS (IDOC MEM)) + (.str "ld" suffix " $dr,@($sr,$slo16)") + (emit (.sym ld suffix -d) dr sr slo16)) + ) +) +(load-op "" OP2_12 WI no-ext-expr) +(load-op b OP2_8 QI ext-expr) +(load-op h OP2_10 HI ext-expr) +(load-op ub OP2_9 QI zext-expr) +(load-op uh OP2_11 HI zext-expr) + +(dni ld-plus "ld+" + ((PIPE O) (IDOC MEM)) + "ld $dr,@$sr+" + (+ OP1_2 dr OP2_14 sr) + (parallel () + ; wip: memory addresses in profiling support + ;(set dr (name ld-mem (mem WI sr))) + (set dr (mem WI sr)) + (set sr (add sr (const 4)))) + ; Note: `pred' is the constraint. Also useful here is (ref name) + ; and returns true if operand <name> was referenced + ; (where "referenced" means _read_ if input operand and _written_ if + ; output operand). + ; args to unit are "unit-name (name1 value1) ..." + ; - cycles(done),issue,pred are also specified this way + ; - if unspecified, default is used + ; - for ins/outs, extra arg is passed that says what was specified + ; - this is AND'd with `written' for outs + ((m32r/d (unit u-load (pred (const 1))) + (unit u-exec (in sr #f) (in dr sr) (out dr sr) (cycles 0) (pred (const 1)))) + (m32rx (unit u-load) + (unit u-exec (in sr #f) (in dr sr) (out dr sr) (cycles 0) (pred (const 1)))) + (m32r2 (unit u-load) + (unit u-exec (in sr #f) (in dr sr) (out dr sr) (cycles 0) (pred (const 1)))) + ) +) + +(dnmi pop "pop" + ((PIPE O) (IDOC MEM)) + "pop $dr" + (emit ld-plus dr (sr 15)) ; "ld %0,@sp+" +) + +(dni ld24 "ld24" + ((IDOC MEM)) + "ld24 $dr,$uimm24" + (+ OP1_14 dr uimm24) + (set dr uimm24) + () +) + +; ldi8 appears before ldi16 so we try the shorter version first + +(dni ldi8 "ldi8" + ((PIPE OS) (IDOC ALU)) + "ldi8 $dr,$simm8" + (+ OP1_6 dr simm8) + (set dr simm8) + () +) + +(dnmi ldi8a "ldi8 alias" + ((PIPE OS) (IDOC ALU)) + "ldi $dr,$simm8" + (emit ldi8 dr simm8) +) + +(dni ldi16 "ldi16" + ((IDOC ALU)) + "ldi16 $dr,$hash$slo16" + (+ OP1_9 OP2_15 (f-r2 0) dr slo16) + (set dr slo16) + () +) + +(dnmi ldi16a "ldi16 alias" + ((IDOC ALU)) + "ldi $dr,$hash$slo16" + (emit ldi16 dr slo16) +) + +(dni lock "lock" + ((PIPE O) (IDOC MISC)) + "lock $dr,@$sr" + (+ OP1_2 OP2_13 dr sr) + (sequence () + (set (reg h-lock) (const BI 1)) + (set dr (mem WI sr))) + ((m32r/d (unit u-load)) + (m32rx (unit u-load)) + (m32r2 (unit u-load))) +) + +(dni machi "machi" + ( + ; (MACH m32r) is a temporary hack. This insn collides with machi-a + ; in the simulator so disable it for m32rx. + (MACH m32r) (PIPE S) (IDOC MAC) + ) + "machi $src1,$src2" + (+ OP1_3 OP2_4 src1 src2) + ; FIXME: TRACE_RESULT will print the wrong thing since we + ; alter one of the arguments. + (set accum + (sra DI + (sll DI + (add DI + accum + (mul DI + (ext DI (and WI src1 (const #xffff0000))) + (ext DI (trunc HI (sra WI src2 (const 16)))))) + (const 8)) + (const 8))) + ((m32r/d (unit u-mac))) +) + +(dni machi-a "machi-a" + ((MACH m32rx,m32r2) (PIPE S) (IDOC MAC)) + "machi $src1,$src2,$acc" + (+ OP1_3 src1 acc (f-op23 4) src2) + (set acc + (sra DI + (sll DI + (add DI + acc + (mul DI + (ext DI (and WI src1 (const #xffff0000))) + (ext DI (trunc HI (sra WI src2 (const 16)))))) + (const 8)) + (const 8))) + ((m32rx (unit u-mac)) + (m32r2 (unit u-mac))) +) + +(dni maclo "maclo" + ((MACH m32r) (PIPE S) (IDOC MAC)) + "maclo $src1,$src2" + (+ OP1_3 OP2_5 src1 src2) + (set accum + (sra DI + (sll DI + (add DI + accum + (mul DI + (ext DI (sll WI src1 (const 16))) + (ext DI (trunc HI src2)))) + (const 8)) + (const 8))) + ((m32r/d (unit u-mac))) +) + +(dni maclo-a "maclo-a" + ((MACH m32rx,m32r2) (PIPE S) (IDOC MAC)) + "maclo $src1,$src2,$acc" + (+ OP1_3 src1 acc (f-op23 5) src2) + (set acc + (sra DI + (sll DI + (add DI + acc + (mul DI + (ext DI (sll WI src1 (const 16))) + (ext DI (trunc HI src2)))) + (const 8)) + (const 8))) + ((m32rx (unit u-mac)) + (m32r2 (unit u-mac))) +) + +(dni macwhi "macwhi" + ((MACH m32r) (PIPE S) (IDOC MAC)) + "macwhi $src1,$src2" + (+ OP1_3 OP2_6 src1 src2) + (set accum + (sra DI + (sll DI + (add DI + accum + (mul DI + (ext DI src1) + (ext DI (trunc HI (sra WI src2 (const 16)))))) + (const 8)) + (const 8))) + ((m32r/d (unit u-mac))) +) + +(dni macwhi-a "macwhi-a" + ((MACH m32rx,m32r2) (PIPE S) SPECIAL (IDOC MAC)) + "macwhi $src1,$src2,$acc" + (+ OP1_3 src1 acc (f-op23 6) src2) + ; Note that this doesn't do the sign extension, which is correct. + (set acc + (add acc + (mul (ext DI src1) + (ext DI (trunc HI (sra src2 (const 16))))))) + ((m32rx (unit u-mac)) + (m32r2 (unit u-mac))) +) + +(dni macwlo "macwlo" + ((MACH m32r) (PIPE S) (IDOC MAC)) + "macwlo $src1,$src2" + (+ OP1_3 OP2_7 src1 src2) + (set accum + (sra DI + (sll DI + (add DI + accum + (mul DI + (ext DI src1) + (ext DI (trunc HI src2)))) + (const 8)) + (const 8))) + ((m32r/d (unit u-mac))) +) + +(dni macwlo-a "macwlo-a" + ((MACH m32rx,m32r2) (PIPE S) SPECIAL (IDOC MAC)) + "macwlo $src1,$src2,$acc" + (+ OP1_3 src1 acc (f-op23 7) src2) + ; Note that this doesn't do the sign extension, which is correct. + (set acc + (add acc + (mul (ext DI src1) + (ext DI (trunc HI src2))))) + ((m32rx (unit u-mac)) + (m32r2 (unit u-mac))) +) + +(dni mul "mul" + ((PIPE S) (IDOC ALU)) + "mul $dr,$sr" + (+ OP1_1 OP2_6 dr sr) + (set dr (mul dr sr)) + ((m32r/d (unit u-exec (cycles 4))) + (m32rx (unit u-exec (cycles 4))) + (m32r2 (unit u-exec (cycles 4)))) +) + +(dni mulhi "mulhi" + ((MACH m32r) (PIPE S) (IDOC ACCUM)) + "mulhi $src1,$src2" + (+ OP1_3 OP2_0 src1 src2) + (set accum + (sra DI + (sll DI + (mul DI + (ext DI (and WI src1 (const #xffff0000))) + (ext DI (trunc HI (sra WI src2 (const 16))))) + (const 16)) + (const 16))) + ((m32r/d (unit u-mac))) +) + +(dni mulhi-a "mulhi-a" + ((MACH m32rx,m32r2) (PIPE S) (IDOC ACCUM)) + "mulhi $src1,$src2,$acc" + (+ OP1_3 (f-op23 0) src1 acc src2) + (set acc + (sra DI + (sll DI + (mul DI + (ext DI (and WI src1 (const #xffff0000))) + (ext DI (trunc HI (sra WI src2 (const 16))))) + (const 16)) + (const 16))) + ((m32rx (unit u-mac)) + (m32r2 (unit u-mac))) +) + +(dni mullo "mullo" + ((MACH m32r) (PIPE S) (IDOC ACCUM)) + "mullo $src1,$src2" + (+ OP1_3 OP2_1 src1 src2) + (set accum + (sra DI + (sll DI + (mul DI + (ext DI (sll WI src1 (const 16))) + (ext DI (trunc HI src2))) + (const 16)) + (const 16))) + ((m32r/d (unit u-mac))) +) + +(dni mullo-a "mullo-a" + ((MACH m32rx,m32r2) (PIPE S) (IDOC ACCUM)) + "mullo $src1,$src2,$acc" + (+ OP1_3 src1 acc (f-op23 1) src2) + (set acc + (sra DI + (sll DI + (mul DI + (ext DI (sll WI src1 (const 16))) + (ext DI (trunc HI src2))) + (const 16)) + (const 16))) + ((m32rx (unit u-mac)) + (m32r2 (unit u-mac))) +) + +(dni mulwhi "mulwhi" + ((MACH m32r) (PIPE S) (IDOC ACCUM)) + "mulwhi $src1,$src2" + (+ OP1_3 OP2_2 src1 src2) + (set accum + (sra DI + (sll DI + (mul DI + (ext DI src1) + (ext DI (trunc HI (sra WI src2 (const 16))))) + (const 8)) + (const 8))) + ((m32r/d (unit u-mac))) +) + +(dni mulwhi-a "mulwhi-a" + ((MACH m32rx,m32r2) (PIPE S) SPECIAL (IDOC ACCUM)) + "mulwhi $src1,$src2,$acc" + (+ OP1_3 src1 acc (f-op23 2) src2) + ; Note that this doesn't do the sign extension, which is correct. + (set acc + (mul (ext DI src1) + (ext DI (trunc HI (sra src2 (const 16)))))) + ((m32rx (unit u-mac)) + (m32r2 (unit u-mac))) +) + +(dni mulwlo "mulwlo" + ((MACH m32r) (PIPE S) (IDOC ACCUM)) + "mulwlo $src1,$src2" + (+ OP1_3 OP2_3 src1 src2) + (set accum + (sra DI + (sll DI + (mul DI + (ext DI src1) + (ext DI (trunc HI src2))) + (const 8)) + (const 8))) + ((m32r/d (unit u-mac))) +) + +(dni mulwlo-a "mulwlo-a" + ((MACH m32rx,m32r2) (PIPE S) SPECIAL (IDOC ACCUM)) + "mulwlo $src1,$src2,$acc" + (+ OP1_3 src1 acc (f-op23 3) src2) + ; Note that this doesn't do the sign extension, which is correct. + (set acc + (mul (ext DI src1) + (ext DI (trunc HI src2)))) + ((m32rx (unit u-mac)) + (m32r2 (unit u-mac))) +) + +(dni mv "mv" + ((PIPE OS) (IDOC ALU)) + "mv $dr,$sr" + (+ OP1_1 OP2_8 dr sr) + (set dr sr) + () +) + +(dni mvfachi "mvfachi" + ((MACH m32r) (PIPE S) (IDOC ACCUM)) + "mvfachi $dr" + (+ OP1_5 OP2_15 (f-r2 0) dr) + (set dr (trunc WI (sra DI accum (const 32)))) + ((m32r/d (unit u-exec (cycles 2)))) +) + +(dni mvfachi-a "mvfachi-a" + ((MACH m32rx,m32r2) (PIPE S) (IDOC ACCUM)) + "mvfachi $dr,$accs" + (+ OP1_5 dr OP2_15 accs (f-op3 0)) + (set dr (trunc WI (sra DI accs (const 32)))) + ((m32rx (unit u-exec (cycles 2))) + (m32r2 (unit u-exec (cycles 2)))) +) + +(dni mvfaclo "mvfaclo" + ((MACH m32r) (PIPE S) (IDOC ACCUM)) + "mvfaclo $dr" + (+ OP1_5 OP2_15 (f-r2 1) dr) + (set dr (trunc WI accum)) + ((m32r/d (unit u-exec (cycles 2)))) +) + +(dni mvfaclo-a "mvfaclo-a" + ((MACH m32rx,m32r2) (PIPE S) (IDOC ACCUM)) + "mvfaclo $dr,$accs" + (+ OP1_5 dr OP2_15 accs (f-op3 1)) + (set dr (trunc WI accs)) + ((m32rx (unit u-exec (cycles 2))) + (m32r2 (unit u-exec (cycles 2)))) +) + +(dni mvfacmi "mvfacmi" + ((MACH m32r) (PIPE S) (IDOC ACCUM)) + "mvfacmi $dr" + (+ OP1_5 OP2_15 (f-r2 2) dr) + (set dr (trunc WI (sra DI accum (const 16)))) + ((m32r/d (unit u-exec (cycles 2)))) +) + +(dni mvfacmi-a "mvfacmi-a" + ((MACH m32rx,m32r2) (PIPE S) (IDOC ACCUM)) + "mvfacmi $dr,$accs" + (+ OP1_5 dr OP2_15 accs (f-op3 2)) + (set dr (trunc WI (sra DI accs (const 16)))) + ((m32rx (unit u-exec (cycles 2))) + (m32r2 (unit u-exec (cycles 2)))) +) + +(dni mvfc "mvfc" + ((PIPE O) (IDOC MISC)) + "mvfc $dr,$scr" + (+ OP1_1 OP2_9 dr scr) + (set dr scr) + () +) + +(dni mvtachi "mvtachi" + ((MACH m32r) (PIPE S) (IDOC ACCUM)) + "mvtachi $src1" + (+ OP1_5 OP2_7 (f-r2 0) src1) + (set accum + (or DI + (and DI accum (const DI #xffffffff)) + (sll DI (ext DI src1) (const 32)))) + ((m32r/d (unit u-exec (in sr src1)))) +) + +(dni mvtachi-a "mvtachi-a" + ((MACH m32rx,m32r2) (PIPE S) (IDOC ACCUM)) + "mvtachi $src1,$accs" + (+ OP1_5 src1 OP2_7 accs (f-op3 0)) + (set accs + (or DI + (and DI accs (const DI #xffffffff)) + (sll DI (ext DI src1) (const 32)))) + ((m32rx (unit u-exec (in sr src1))) + (m32r2 (unit u-exec (in sr src1)))) +) + +(dni mvtaclo "mvtaclo" + ((MACH m32r) (PIPE S) (IDOC ACCUM)) + "mvtaclo $src1" + (+ OP1_5 OP2_7 (f-r2 1) src1) + (set accum + (or DI + (and DI accum (const DI #xffffffff00000000)) + (zext DI src1))) + ((m32r/d (unit u-exec (in sr src1)))) +) + +(dni mvtaclo-a "mvtaclo-a" + ((MACH m32rx,m32r2) (PIPE S) (IDOC ACCUM)) + "mvtaclo $src1,$accs" + (+ OP1_5 src1 OP2_7 accs (f-op3 1)) + (set accs + (or DI + (and DI accs (const DI #xffffffff00000000)) + (zext DI src1))) + ((m32rx (unit u-exec (in sr src1))) + (m32r2 (unit u-exec (in sr src1)))) +) + +(dni mvtc "mvtc" + ((PIPE O) (IDOC MISC)) + "mvtc $sr,$dcr" + (+ OP1_1 OP2_10 dcr sr) + (set dcr sr) + () +) + +(dni neg "neg" + ((PIPE OS) (IDOC ALU)) + "neg $dr,$sr" + (+ OP1_0 OP2_3 dr sr) + (set dr (neg sr)) + () +) + +(dni nop "nop" + ((PIPE OS) (IDOC MISC)) + "nop" + (+ OP1_7 OP2_0 (f-r1 0) (f-r2 0)) + (c-code VOID "PROFILE_COUNT_FILLNOPS (current_cpu, abuf->addr);\n") + ; FIXME: quick hack: parallel nops don't contribute to cycle count. + ; Other kinds of nops do however (which we currently ignore). + ((m32r/d (unit u-exec (cycles 0))) + (m32rx (unit u-exec (cycles 0))) + (m32r2 (unit u-exec (cycles 0)))) +) + +(dni not "not" + ((PIPE OS) (IDOC ALU)) + "not $dr,$sr" + (+ OP1_0 OP2_11 dr sr) + (set dr (inv sr)) + () +) + +(dni rac "rac" + ((MACH m32r) (PIPE S) (IDOC MAC)) + "rac" + (+ OP1_5 OP2_9 (f-r1 0) (f-r2 0)) + (sequence ((DI tmp1)) + (set tmp1 (sll DI accum (const 1))) + (set tmp1 (add DI tmp1 (const DI #x8000))) + (set accum + (cond DI + ((gt tmp1 (const DI #x00007fffffff0000)) + (const DI #x00007fffffff0000)) + ((lt tmp1 (const DI #xffff800000000000)) + (const DI #xffff800000000000)) + (else (and tmp1 (const DI #xffffffffffff0000))))) + ) + ((m32r/d (unit u-mac))) +) + +(dni rac-dsi "rac-dsi" + ((MACH m32rx,m32r2) (PIPE S) (IDOC MAC)) + "rac $accd,$accs,$imm1" + (+ OP1_5 accd (f-bits67 0) OP2_9 accs (f-bit14 0) imm1) + (sequence ((DI tmp1)) + (set tmp1 (sll accs imm1)) + (set tmp1 (add tmp1 (const DI #x8000))) + (set accd + (cond DI + ((gt tmp1 (const DI #x00007fffffff0000)) + (const DI #x00007fffffff0000)) + ((lt tmp1 (const DI #xffff800000000000)) + (const DI #xffff800000000000)) + (else (and tmp1 (const DI #xffffffffffff0000))))) + ) + ((m32rx (unit u-mac)) + (m32r2 (unit u-mac))) +) + +(dnmi rac-d "rac-d" + ((MACH m32rx,m32r2) (PIPE S) (IDOC MAC)) + "rac $accd" + (emit rac-dsi accd (f-accs 0) (f-imm1 0)) +) + +(dnmi rac-ds "rac-ds" + ((MACH m32rx,m32r2) (PIPE S) (IDOC MAC)) + "rac $accd,$accs" + (emit rac-dsi accd accs (f-imm1 0)) +) + + +(dni rach "rach" + ((MACH m32r) (PIPE S) (IDOC MAC)) + "rach" + (+ OP1_5 OP2_8 (f-r1 0) (f-r2 0)) + (sequence ((DI tmp1)) + ; Lop off top 8 bits. + ; The sign bit we want to use is bit 55 so the 64 bit value + ; isn't properly signed which we deal with in the if's below. + (set tmp1 (and accum (const DI #xffffffffffffff))) + (if (andif (ge tmp1 (const DI #x003fff80000000)) + (le tmp1 (const DI #x7fffffffffffff))) + (set tmp1 (const DI #x003fff80000000)) + ; else part + (if (andif (ge tmp1 (const DI #x80000000000000)) + (le tmp1 (const DI #xffc00000000000))) + (set tmp1 (const DI #xffc00000000000)) + (set tmp1 (and (add accum (const DI #x40000000)) + (const DI #xffffffff80000000))))) + (set tmp1 (sll tmp1 (const 1))) + ; Sign extend top 8 bits. + (set accum + ; FIXME: 7? + (sra DI (sll DI tmp1 (const 7)) (const 7))) + ) + ((m32r/d (unit u-mac))) +) + +(dni rach-dsi "rach-dsi" + ((MACH m32rx,m32r2) (PIPE S) (IDOC MAC)) + "rach $accd,$accs,$imm1" + (+ OP1_5 accd (f-bits67 0) OP2_8 accs (f-bit14 0) imm1) + (sequence ((DI tmp1)) + (set tmp1 (sll accs imm1)) + (set tmp1 (add tmp1 (const DI #x80000000))) + (set accd + (cond DI + ((gt tmp1 (const DI #x00007fff00000000)) + (const DI #x00007fff00000000)) + ((lt tmp1 (const DI #xffff800000000000)) + (const DI #xffff800000000000)) + (else (and tmp1 (const DI #xffffffff00000000))))) + ) + ((m32rx (unit u-mac)) + (m32r2 (unit u-mac))) +) + +(dnmi rach-d "rach-d" + ((MACH m32rx,m32r2) (PIPE S) (IDOC MAC)) + "rach $accd" + (emit rach-dsi accd (f-accs 0) (f-imm1 0)) +) + +(dnmi rach-ds "rach-ds" + ((MACH m32rx,m32r2) (PIPE S) (IDOC MAC)) + "rach $accd,$accs" + (emit rach-dsi accd accs (f-imm1 0)) +) + +(dni rte "rte" + (UNCOND-CTI (PIPE O) (IDOC BR)) + "rte" + (+ OP1_1 OP2_13 (f-r1 0) (f-r2 6)) + (sequence () + ; pc = bpc & -4 + (set pc (and (reg h-cr 6) (const -4))) + ; bpc = bbpc + (set (reg h-cr 6) (reg h-cr 14)) + ; psw = bpsw + (set (reg h-psw) (reg h-bpsw)) + ; bpsw = bbpsw + (set (reg h-bpsw) (reg h-bbpsw)) + ) + () +) + +(dni seth "seth" + ((IDOC ALU)) + "seth $dr,$hash$hi16" + (+ OP1_13 OP2_12 dr (f-r2 0) hi16) + (set dr (sll WI hi16 (const 16))) + () +) + +(define-pmacro (shift-op sym op2-r-op op2-3-op op2-i-op sem-op) + (begin + (dni sym sym ((PIPE O_OS) (IDOC ALU)) + (.str sym " $dr,$sr") + (+ OP1_1 op2-r-op dr sr) + (set dr (sem-op dr (and sr (const 31)))) + () + ) + (dni (.sym sym "3") sym ((IDOC ALU)) + (.str sym "3 $dr,$sr,$simm16") + (+ OP1_9 op2-3-op dr sr simm16) + (set dr (sem-op sr (and WI simm16 (const 31)))) + () + ) + (dni (.sym sym "i") sym ((PIPE O_OS) (IDOC ALU)) + (.str sym "i $dr,$uimm5") + (+ OP1_5 (f-shift-op2 op2-i-op) dr uimm5) + (set dr (sem-op dr uimm5)) + () + ) + ) +) +(shift-op sll OP2_4 OP2_12 2 sll) +(shift-op sra OP2_2 OP2_10 1 sra) +(shift-op srl OP2_0 OP2_8 0 srl) + +(define-pmacro (store-op suffix op2-op mode) + (begin + (dni (.sym st suffix) (.str "st" suffix) + ((PIPE O) (IDOC MEM)) + (.str "st" suffix " $src1,@$src2") + (+ OP1_2 op2-op src1 src2) + (set mode (mem mode src2) src1) + ((m32r/d (unit u-store (cycles 1))) + (m32rx (unit u-store (cycles 1))) + (m32r2 (unit u-store (cycles 1)))) + ) + (dnmi (.sym st suffix "-2") (.str "st" suffix "-2") + (NO-DIS (PIPE O) (IDOC MEM)) + (.str "st" suffix " $src1,@($src2)") + (emit (.sym st suffix) src1 src2)) + (dni (.sym st suffix -d) (.str "st" suffix "-d") + ((IDOC MEM)) + (.str "st" suffix " $src1,@($slo16,$src2)") + (+ OP1_10 op2-op src1 src2 slo16) + (set mode (mem mode (add src2 slo16)) src1) + ((m32r/d (unit u-store (cycles 2))) + (m32rx (unit u-store (cycles 2))) + (m32r2 (unit u-store (cycles 2)))) + ) + (dnmi (.sym st suffix -d2) (.str "st" suffix "-d2") + (NO-DIS (IDOC MEM)) + (.str "st" suffix " $src1,@($src2,$slo16)") + (emit (.sym st suffix -d) src1 src2 slo16)) + ) +) +(store-op "" OP2_4 WI) +(store-op b OP2_0 QI) +(store-op h OP2_2 HI) + +(dni st-plus "st+" + ((PIPE O) (IDOC MEM)) + "st $src1,@+$src2" + (+ OP1_2 OP2_6 src1 src2) + ; This has to be coded carefully to avoid an "earlyclobber" of src2. + (sequence ((WI new-src2)) + (set new-src2 (add WI src2 (const WI 4))) + (set (mem WI new-src2) src1) + (set src2 new-src2)) + ((m32r/d (unit u-store) + (unit u-exec (in dr src2) (out dr src2) (cycles 0))) + (m32rx (unit u-store) + (unit u-exec (in dr src2) (out dr src2) (cycles 0))) + (m32r2 (unit u-store) + (unit u-exec (in dr src2) (out dr src2) (cycles 0))) + ) +) + +(dni sth-plus "sth+" + ((MACH m32rx,m32r2) (PIPE O) SPECIAL) + "sth $src1,@$src2+" + (+ OP1_2 OP2_3 src1 src2) + ; This has to be coded carefully to avoid an "earlyclobber" of src2. + (sequence ((WI new-src2)) + (set new-src2 src2) + (set (mem HI new-src2) src1) + (set src2 (add new-src2 (const 2)))) + ((m32rx (unit u-store) + (unit u-exec (in dr src2) (out dr src2) (cycles 0))) + (m32r2 (unit u-store) + (unit u-exec (in dr src2) (out dr src2) (cycles 0))) + ) +) + +(dni stb-plus "stb+" + ((MACH m32rx,m32r2) (PIPE O) SPECIAL) + "stb $src1,@$src2+" + (+ OP1_2 OP2_1 src1 src2) + ; This has to be coded carefully to avoid an "earlyclobber" of src2. + (sequence ((WI new-src2)) + (set new-src2 src2) + (set (mem QI new-src2) src1) + (set src2 (add new-src2 (const 1)))) + ((m32rx (unit u-store) + (unit u-exec (in dr src2) (out dr src2) (cycles 0))) + (m32r2 (unit u-store) + (unit u-exec (in dr src2) (out dr src2) (cycles 0))) + ) +) + +(dni st-minus "st-" + ((PIPE O) (IDOC MEM)) + "st $src1,@-$src2" + (+ OP1_2 OP2_7 src1 src2) + ; This is the original way. It doesn't work for parallel execution + ; because of the earlyclobber of src2. + ;(sequence () + ; (set src2 (sub src2 (const 4))) + ; (set (mem WI src2) src1)) + (sequence ((WI new-src2)) + (set new-src2 (sub src2 (const 4))) + (set (mem WI new-src2) src1) + (set src2 new-src2)) + ((m32r/d (unit u-store) + (unit u-exec (in dr src2) (out dr src2) (cycles 0))) + (m32rx (unit u-store) + (unit u-exec (in dr src2) (out dr src2) (cycles 0))) + (m32r2 (unit u-store) + (unit u-exec (in dr src2) (out dr src2) (cycles 0))) + ) +) + +(dnmi push "push" ((PIPE O) (IDOC MEM)) + "push $src1" + (emit st-minus src1 (src2 15)) ; "st %0,@-sp" +) + +(dni sub "sub" + ((PIPE OS) (IDOC ALU)) + "sub $dr,$sr" + (+ OP1_0 OP2_2 dr sr) + (set dr (sub dr sr)) + () +) + +(dni subv "sub:rv" + ((PIPE OS) (IDOC ALU)) + "subv $dr,$sr" + (+ OP1_0 OP2_0 dr sr) + (parallel () + (set dr (sub dr sr)) + (set condbit (sub-oflag dr sr (const 0)))) + () +) + +(dni subx "sub:rx" + ((PIPE OS) (IDOC ALU)) + "subx $dr,$sr" + (+ OP1_0 OP2_1 dr sr) + (parallel () + (set dr (subc dr sr condbit)) + (set condbit (sub-cflag dr sr condbit))) + () +) + +(dni trap "trap" + (UNCOND-CTI FILL-SLOT (PIPE O) (IDOC MISC)) + "trap $uimm4" + (+ OP1_1 OP2_15 (f-r1 0) uimm4) + (sequence () + ; bbpc = bpc + (set (reg h-cr 14) (reg h-cr 6)) + ; Set bpc to the return address. Actually it's not quite the + ; return address as RTE rounds the address down to a word + ; boundary. + (set (reg h-cr 6) (add pc (const 4))) + ; bbpsw = bpsw + (set (reg h-bbpsw) (reg h-bpsw)) + ; bpsw = psw + (set (reg h-bpsw) (reg h-psw)) + ; sm is unchanged, ie,c are set to zero. + (set (reg h-psw) (and (reg h-psw) (const #x80))) + ; m32r_trap handles operating vs user mode + (set WI pc (c-call WI "m32r_trap" pc uimm4)) + ) + () +) + +(dni unlock "unlock" + ((PIPE O) (IDOC MISC)) + "unlock $src1,@$src2" + (+ OP1_2 OP2_5 src1 src2) + (sequence () + (if (reg h-lock) + (set (mem WI src2) src1)) + (set (reg h-lock) (const BI 0))) + ((m32r/d (unit u-load)) + (m32rx (unit u-load)) + (m32r2 (unit u-load))) +) + +; Saturate into byte. +(dni satb "satb" + ((MACH m32rx,m32r2) (IDOC ALU)) + "satb $dr,$sr" + (+ OP1_8 dr OP2_6 sr (f-uimm16 #x0300)) + (set dr + ; FIXME: min/max would simplify this nicely of course. + (cond WI + ((ge sr (const 127)) (const 127)) + ((le sr (const -128)) (const -128)) + (else sr))) + () +) + +; Saturate into half word. +(dni sath "sath" + ((MACH m32rx,m32r2) (IDOC ALU)) + "sath $dr,$sr" + (+ OP1_8 dr OP2_6 sr (f-uimm16 #x0200)) + (set dr + (cond WI + ((ge sr (const 32767)) (const 32767)) + ((le sr (const -32768)) (const -32768)) + (else sr))) + () +) + +; Saturate word. +(dni sat "sat" + ((MACH m32rx,m32r2) SPECIAL (IDOC ALU)) + "sat $dr,$sr" + (+ OP1_8 dr OP2_6 sr (f-uimm16 0)) + (set dr + (if WI condbit + (if WI (lt sr (const 0)) + (const #x7fffffff) + (const #x80000000)) + sr)) + () +) + +; Parallel compare byte zeros. +; Set C bit in condition register if any byte in source register is zero. +(dni pcmpbz "pcmpbz" + ((MACH m32rx,m32r2) (PIPE OS) SPECIAL (IDOC ALU)) + "pcmpbz $src2" + (+ OP1_0 (f-r1 3) OP2_7 src2) + (set condbit + (cond BI + ((eq (and src2 (const #xff)) (const 0)) (const BI 1)) + ((eq (and src2 (const #xff00)) (const 0)) (const BI 1)) + ((eq (and src2 (const #xff0000)) (const 0)) (const BI 1)) + ((eq (and src2 (const #xff000000)) (const 0)) (const BI 1)) + (else (const BI 0)))) + ((m32rx (unit u-cmp)) + (m32r2 (unit u-cmp))) +) + +; Add accumulators +(dni sadd "sadd" + ((MACH m32rx,m32r2) (PIPE S) (IDOC ACCUM)) + "sadd" + (+ OP1_5 (f-r1 0) OP2_14 (f-r2 4)) + (set (reg h-accums 0) + (add (sra (reg h-accums 1) (const 16)) + (reg h-accums 0))) + ((m32rx (unit u-mac)) + (m32r2 (unit u-mac))) +) + +; Multiply and add into accumulator 1 +(dni macwu1 "macwu1" + ((MACH m32rx,m32r2) (PIPE S) (IDOC MAC)) + "macwu1 $src1,$src2" + (+ OP1_5 src1 OP2_11 src2) + (set (reg h-accums 1) + (sra DI + (sll DI + (add DI + (reg h-accums 1) + (mul DI + (ext DI src1) + (ext DI (and src2 (const #xffff))))) + (const 8)) + (const 8))) + ((m32rx (unit u-mac)) + (m32r2 (unit u-mac))) +) + +; Multiply and subtract from accumulator 0 +(dni msblo "msblo" + ((MACH m32rx,m32r2) (PIPE S) (IDOC MAC)) + "msblo $src1,$src2" + (+ OP1_5 src1 OP2_13 src2) + (set accum + (sra DI + (sll DI + (sub accum + (sra DI + (sll DI + (mul DI + (ext DI (trunc HI src1)) + (ext DI (trunc HI src2))) + (const 32)) + (const 16))) + (const 8)) + (const 8))) + ((m32rx (unit u-mac)) + (m32r2 (unit u-mac))) +) + +; Multiply into accumulator 1 +(dni mulwu1 "mulwu1" + ((MACH m32rx,m32r2) (PIPE S) (IDOC MAC)) + "mulwu1 $src1,$src2" + (+ OP1_5 src1 OP2_10 src2) + (set (reg h-accums 1) + (sra DI + (sll DI + (mul DI + (ext DI src1) + (ext DI (and src2 (const #xffff)))) + (const 16)) + (const 16))) + ((m32rx (unit u-mac)) + (m32r2 (unit u-mac))) +) + +; Multiply and add into accumulator 1 +(dni maclh1 "maclh1" + ((MACH m32rx,m32r2) (PIPE S) (IDOC MAC)) + "maclh1 $src1,$src2" + (+ OP1_5 src1 OP2_12 src2) + (set (reg h-accums 1) + (sra DI + (sll DI + (add DI + (reg h-accums 1) + (sll DI + (ext DI + (mul SI + (ext SI (trunc HI src1)) + (sra SI src2 (const SI 16)))) + (const 16))) + (const 8)) + (const 8))) + ((m32rx (unit u-mac)) + (m32r2 (unit u-mac))) +) + +; skip instruction if C +(dni sc "sc" + ((MACH m32rx,m32r2) (PIPE O) SPECIAL (IDOC BR)) + "sc" + (+ OP1_7 (f-r1 4) OP2_0 (f-r2 1)) + (skip (zext INT condbit)) + () +) + +; skip instruction if not C +(dni snc "snc" + ((MACH m32rx,m32r2) (PIPE O) SPECIAL (IDOC BR)) + "snc" + (+ OP1_7 (f-r1 5) OP2_0 (f-r2 1)) + (skip (zext INT (not condbit))) + () +) + +; PSW &= ((~ uimm8) | 0xff00) +(dni clrpsw "clrpsw" + ((PIPE O) SPECIAL_M32R) + "clrpsw $uimm8" + (+ OP1_7 (f-r1 2) uimm8) + (set USI (reg h-cr 0) + (and USI (reg h-cr 0) + (or USI (zext SI (inv QI uimm8)) (const #xff00)))) + () +) + +; PSW |= (unsigned char) uimm8 +(dni setpsw "setpsw" + ((PIPE O) SPECIAL_M32R) + "setpsw $uimm8" + (+ OP1_7 (f-r1 1) uimm8) + (set USI (reg h-cr 0) uimm8) + () +) + +; bset +(dni bset "bset" + (SPECIAL_M32R) + "bset $uimm3,@($slo16,$sr)" + (+ OP1_10 (f-bit4 0) uimm3 OP2_6 sr slo16) + (set QI (mem QI (add sr slo16)) + (or QI (mem QI (add sr slo16)) + (sll QI (const 1) (sub (const 7) uimm3)))) + () +) + +; bclr +(dni bclr "bclr" + (SPECIAL_M32R) + "bclr $uimm3,@($slo16,$sr)" + (+ OP1_10 (f-bit4 0) uimm3 OP2_7 sr slo16) + (set QI (mem QI (add sr slo16)) + (and QI (mem QI (add sr slo16)) + (inv QI (sll QI (const 1) (sub (const 7) uimm3))))) + () +) + +; btst +(dni btst "btst" + (SPECIAL_M32R (PIPE O)) + "btst $uimm3,$sr" + (+ OP1_0 (f-bit4 0) uimm3 OP2_15 sr) + (set condbit (and QI (srl QI sr (sub (const 7) uimm3)) (const 1))) + () +) diff --git a/cpu/m32r.opc b/cpu/m32r.opc new file mode 100644 index 00000000000..3100fee9f92 --- /dev/null +++ b/cpu/m32r.opc @@ -0,0 +1,324 @@ +/* M32R opcode support. -*- C -*- + + Copyright 1998, 1999, 2000, 2001, 2004, 2005, 2007, 2009 + Free Software Foundation, Inc. + + Contributed by Red Hat Inc; developed under contract from + Mitsubishi Electric Corporation. + + 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. */ + + +/* This file is an addendum to m32r.cpu. Heavy use of C code isn't + appropriate in .cpu files, so it resides here. This especially applies + to assembly/disassembly where parsing/printing can be quite involved. + Such things aren't really part of the specification of the cpu, per se, + so .cpu files provide the general framework and .opc files handle the + nitty-gritty details as necessary. + + Each section is delimited with start and end markers. + + <arch>-opc.h additions use: "-- opc.h" + <arch>-opc.c additions use: "-- opc.c" + <arch>-asm.c additions use: "-- asm.c" + <arch>-dis.c additions use: "-- dis.c" + <arch>-ibd.h additions use: "-- ibd.h" */ + +/* -- opc.h */ + +#undef CGEN_DIS_HASH_SIZE +#define CGEN_DIS_HASH_SIZE 256 +#undef CGEN_DIS_HASH +#if 0 +#define X(b) (((unsigned char *) (b))[0] & 0xf0) +#define CGEN_DIS_HASH(buffer, value) \ +(X (buffer) | \ + (X (buffer) == 0x40 || X (buffer) == 0xe0 || X (buffer) == 0x60 || X (buffer) == 0x50 ? 0 \ + : X (buffer) == 0x70 || X (buffer) == 0xf0 ? (((unsigned char *) (buffer))[0] & 0xf) \ + : X (buffer) == 0x30 ? ((((unsigned char *) (buffer))[1] & 0x70) >> 4) \ + : ((((unsigned char *) (buffer))[1] & 0xf0) >> 4))) +#else +#define CGEN_DIS_HASH(buffer, value) m32r_cgen_dis_hash (buffer, value) +extern unsigned int m32r_cgen_dis_hash (const char *, CGEN_INSN_INT); +#endif + +/* -- */ + +/* -- opc.c */ +unsigned int +m32r_cgen_dis_hash (const char * buf ATTRIBUTE_UNUSED, CGEN_INSN_INT value) +{ + unsigned int x; + + if (value & 0xffff0000) /* 32bit instructions. */ + value = (value >> 16) & 0xffff; + + x = (value >> 8) & 0xf0; + if (x == 0x40 || x == 0xe0 || x == 0x60 || x == 0x50) + return x; + + if (x == 0x70 || x == 0xf0) + return x | ((value >> 8) & 0x0f); + + if (x == 0x30) + return x | ((value & 0x70) >> 4); + else + return x | ((value & 0xf0) >> 4); +} + +/* -- */ + +/* -- asm.c */ +static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'"); + +/* Handle '#' prefixes (i.e. skip over them). */ + +static const char * +parse_hash (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + const char **strp, + int opindex ATTRIBUTE_UNUSED, + long *valuep ATTRIBUTE_UNUSED) +{ + if (**strp == '#') + ++*strp; + return NULL; +} + +/* Handle shigh(), high(). */ + +static const char * +parse_hi16 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + if (**strp == '#') + ++*strp; + + if (strncasecmp (*strp, "high(", 5) == 0) + { + *strp += 5; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_HI16_ULO, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + { + value >>= 16; + value &= 0xffff; + } + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp, "shigh(", 6) == 0) + { + *strp += 6; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_HI16_SLO, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + { + value += 0x8000; + value >>= 16; + value &= 0xffff; + } + *valuep = value; + return errmsg; + } + + return cgen_parse_unsigned_integer (cd, strp, opindex, valuep); +} + +/* Handle low() in a signed context. Also handle sda(). + The signedness of the value doesn't matter to low(), but this also + handles the case where low() isn't present. */ + +static const char * +parse_slo16 (CGEN_CPU_DESC cd, + const char ** strp, + int opindex, + long * valuep) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + if (**strp == '#') + ++*strp; + + if (strncasecmp (*strp, "low(", 4) == 0) + { + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_LO16, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = ((value & 0xffff) ^ 0x8000) - 0x8000; + *valuep = value; + return errmsg; + } + + if (strncasecmp (*strp, "sda(", 4) == 0) + { + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_SDA16, + NULL, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + *valuep = value; + return errmsg; + } + + return cgen_parse_signed_integer (cd, strp, opindex, valuep); +} + +/* Handle low() in an unsigned context. + The signedness of the value doesn't matter to low(), but this also + handles the case where low() isn't present. */ + +static const char * +parse_ulo16 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + if (**strp == '#') + ++*strp; + + if (strncasecmp (*strp, "low(", 4) == 0) + { + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_LO16, + & result_type, & value); + if (**strp != ')') + return MISSING_CLOSING_PARENTHESIS; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + + return cgen_parse_unsigned_integer (cd, strp, opindex, valuep); +} + +/* -- */ + +/* -- dis.c */ +/* Immediate values are prefixed with '#'. */ + +#define CGEN_PRINT_NORMAL(cd, info, value, attrs, pc, length) \ + do \ + { \ + if (CGEN_BOOL_ATTR ((attrs), CGEN_OPERAND_HASH_PREFIX)) \ + (*info->fprintf_func) (info->stream, "#"); \ + } \ + while (0) + +/* Handle '#' prefixes as operands. */ + +static void +print_hash (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value ATTRIBUTE_UNUSED, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + disassemble_info *info = (disassemble_info *) dis_info; + + (*info->fprintf_func) (info->stream, "#"); +} + +#undef CGEN_PRINT_INSN +#define CGEN_PRINT_INSN my_print_insn + +static int +my_print_insn (CGEN_CPU_DESC cd, + bfd_vma pc, + disassemble_info *info) +{ + bfd_byte buffer[CGEN_MAX_INSN_SIZE]; + bfd_byte *buf = buffer; + int status; + int buflen = (pc & 3) == 0 ? 4 : 2; + int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG; + bfd_byte *x; + + /* Read the base part of the insn. */ + + status = (*info->read_memory_func) (pc - ((!big_p && (pc & 3) != 0) ? 2 : 0), + buf, buflen, info); + if (status != 0) + { + (*info->memory_error_func) (status, pc, info); + return -1; + } + + /* 32 bit insn? */ + x = (big_p ? &buf[0] : &buf[3]); + if ((pc & 3) == 0 && (*x & 0x80) != 0) + return print_insn (cd, pc, info, buf, buflen); + + /* Print the first insn. */ + if ((pc & 3) == 0) + { + buf += (big_p ? 0 : 2); + if (print_insn (cd, pc, info, buf, 2) == 0) + (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); + buf += (big_p ? 2 : -2); + } + + x = (big_p ? &buf[0] : &buf[1]); + if (*x & 0x80) + { + /* Parallel. */ + (*info->fprintf_func) (info->stream, " || "); + *x &= 0x7f; + } + else + (*info->fprintf_func) (info->stream, " -> "); + + /* The "& 3" is to pass a consistent address. + Parallel insns arguably both begin on the word boundary. + Also, branch insns are calculated relative to the word boundary. */ + if (print_insn (cd, pc & ~ (bfd_vma) 3, info, buf, 2) == 0) + (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); + + return (pc & 3) ? 2 : 4; +} + +/* -- */ diff --git a/cpu/mt.cpu b/cpu/mt.cpu new file mode 100644 index 00000000000..bb987f31d7b --- /dev/null +++ b/cpu/mt.cpu @@ -0,0 +1,1352 @@ +; Morpho Technologies MT Arch description. -*- Scheme -*- +; Copyright 2001, 2007, 2009 Free Software Foundation, Inc. +; +; Contributed by Red Hat Inc; developed under contract from +; Morpho Technologies. +; +; 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 The Architecture, Attributes, ISA, CPU, Machine, And Model. ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; define-arch must appear first +(define-arch + (name mt) ; name of cpu family + (comment "Morpho Technologies mRISC family") + (default-alignment aligned) + (insn-lsb0? #t) + (machs ms1 ms1-003 ms2) + (isas mt) +) + +; Instruction set parameters. + +(define-isa + (name mt) + (comment "Morpho Technologies MT ISA") + (default-insn-word-bitsize 32) + (default-insn-bitsize 32) + (base-insn-bitsize 32) + (parallel-insns 2) +) + +; Cpu family definitions. + + +(define-cpu + ; cpu names must be distinct from the architecture name and machine names. + (name ms1bf) + (comment "Morpho Technologies mRISC family") + (endian big) + (word-bitsize 32) +) + +(define-cpu + ; cpu names must be distinct from the architecture name and machine names. + (name ms1-003bf) + (comment "Morpho Technologies mRISC family") + (endian big) + (word-bitsize 32) +) + +(define-cpu + ; cpu names must be distinct from the architecture name and machine names. + (name ms2bf) + (comment "Morpho Technologies mRISC family") + (endian big) + (word-bitsize 32) +) + +(define-mach + (name ms1) + (comment "Morpho Technologies mrisc") + (cpu ms1bf) + (isas mt) +) + +(define-mach + (name ms1-003) + (comment "Morpho Technologies mrisc") + (cpu ms1-003bf) + (isas mt) +) + +(define-mach + (name ms2) + (comment "Morpho Technologies ms2") + (cpu ms2bf) + (isas mt) +) + + +; Model descriptions. +; Can probably take the u-exec out. We'll see. +(define-model + (name ms1) + (comment "Morpho Technologies mrisc") + (mach ms1) + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) +) + +(define-model + (name ms1-003) + (comment "Morpho Technologies mrisc") + (mach ms1-003) + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) +) + +(define-model + (name ms2) + (comment "Morpho Technologies ms2") + (mach ms2) + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + () ; inputs + () ; outputs + () ; profile action (default) + ) +) + +; FIXME: It might simplify things to separate the execute process from the +; one that updates the PC. + + +;;;;;;;;;;;;;;;;;;;;;;;; +;; Instruction Fields ;; +;;;;;;;;;;;;;;;;;;;;;;;; + +; Attributes: +; PCREL-ADDR: pc relative value (for reloc and disassembly purposes) +; ABS-ADDR: absolute address (for reloc and disassembly purposes?) +; RESERVED: bits are not used to decode insn, must be all 0 +; RELOC: there is a relocation associated with this field (experiment) +; +; f-msys: Identify a a morphosys insns. 1 if msys, 0 if not. +; f-opc: 6 bit opcode for non-morphosys instructions. +; f-msopc: 6 bit opcode for morphosys instructions. +; f-imm: flag to indicate use of an immediate operand. 1 if yes, 0 if no. +; f-sr1: source resgister 1. (also used for MSYS insns) +; f-sr2: source register 2. (also used for MSYS insns) +; f-dr: destination register when located in bits 19:16. +; f-drrr: destination register when located in bits 15:12. (also for MSYS insns) +; f-imm16: 16 bit immediate value when not an offset. +; f-imm16a: 16 bit immediate value when it's a pc-rel offset. +; f-uu4a: unused 4 bit field. +; f-uu4b: second unsed 4 bit field. +; f-uu1: unused 1 bit field +; f-uu12: unused 12 bit field. +; f-uu16: unused 16 bit field. +; f-uu24: unused 24 bit field. + +(dnf f-msys "morphosys insn flag" () 31 1) +(dnf f-opc "opcode field" () 30 6) +(dnf f-imm "immedate flag" () 24 1) +(dnf f-uu24 "unused 24 bits" () 23 24) +(dnf f-sr1 "sr1 register field" (ABS-ADDR) 23 4) +(dnf f-sr2 "sr2 register field" (ABS-ADDR) 19 4) +(dnf f-dr "dr register field" (ABS-ADDR) 19 4) +(dnf f-drrr "drrr register field" (ABS-ADDR) 15 4) +(dnf f-imm16u "unsigned 16 bit immediate" () 15 16) +(df f-imm16s "signed 16 bit immediate" () 15 16 INT ((value pc) (add HI value 0)) ((value pc) (add HI value 0))) +(dnf f-imm16a "pc-rel offset" (PCREL-ADDR) 15 16) +(dnf f-uu4a "unused 4 bit field" () 19 4) +(dnf f-uu4b "unused 4 bit field" () 23 4) +(dnf f-uu12 "unused 12 bit field" () 11 12) +(dnf f-uu8 "unused 8 bit field" () 15 8) +(dnf f-uu16 "unused 16 bit field" () 15 16) +(dnf f-uu1 "unused 1 bit field" () 7 1) + +; The following ifields are used exclusively for the MorphoSys instructions. +; In a few cases, a bit field is used for something in addition to what its +; name suggests. For the most part, the names are meaningful though. + +(dnf f-msopc "opcode field" () 30 5) +(dnf f-uu-26-25 "unused 26 bits" () 25 26) +(dnf f-mask "mask" () 25 16) +(dnf f-bankaddr "bank address" () 25 13) +(dnf f-rda "rda" () 25 1) +(dnf f-uu-2-25 "unused bits 25 & 24" () 25 2) +(dnf f-rbbc "Omega network configuration" () 25 2) +(dnf f-perm "perm" () 25 2) +(dnf f-mode "mode" () 25 2) +(dnf f-uu-1-24 "testing" () 24 1) +(dnf f-wr "wr" () 24 1) +(dnf f-fbincr "fb incr" () 23 4) +(dnf f-uu-2-23 "unused bits 23 and 22" () 23 2) +(dnf f-xmode "xmode" () 23 1) +(dnf f-a23 "a23" () 23 1) +(dnf f-mask1 "mask1" () 22 3) +(dnf f-cr "cr" () 22 3) +(dnf f-type "type" () 21 2) +(dnf f-incamt "increment amount" () 19 8) +(dnf f-cbs "cbs" () 19 2) +(dnf f-uu-1-19 "unused bit 19" () 19 1) +(dnf f-ball "b_all" () 19 1) +(dnf f-colnum "column number" () 18 3) +(dnf f-brc "b_r_c" () 18 3) +(dnf f-incr "incr" () 17 6) +(dnf f-fbdisp "frame buffer displacement" () 15 6) +(dnf f-uu-4-15 "unused bits 15,14,13,12" () 15 4) +(dnf f-length "length" () 15 3) +(dnf f-uu-1-15 "unused bit 15" () 15 1) +(dnf f-rc "row/column context" () 15 1) +(dnf f-rcnum "starting cell of cntxt mem." () 14 3) +(dnf f-rownum "row number" () 14 3) +(dnf f-cbx "cbx" () 14 3) +(dnf f-id "id" () 14 1) +(dnf f-size "size" () 13 14) +(dnf f-rownum1 "row number" () 12 3) +(dnf f-uu-3-11 "unused 3 bits (11-9)" () 11 3) +(dnf f-rc1 "row/column context" () 11 1) +(dnf f-ccb "ccb" () 11 1) +(dnf f-cbrb "data-bus orientation" () 10 1) +(dnf f-cdb "cdb" () 10 1) +(dnf f-rownum2 "row number" () 9 3) +(dnf f-cell "cell" () 9 3) +(dnf f-uu-3-9 "unused 3 bits (9-7)" () 9 3) +(dnf f-contnum "context number" () 8 9) +(dnf f-uu-1-6 "unused bit 6" () 6 1) +(dnf f-dup "dup" () 6 1) +(dnf f-rc2 "rc2" () 6 1) +(dnf f-ctxdisp "context displacement" () 5 6) + +; additional fields in ms2 +(dnf f-imm16l "loop count" () 23 16) +(df f-loopo "loop offset" () 7 8 UINT + ((value pc) (srl SI value 2)) + ((value pc) (add SI (sll value 2) 8)) + ) +(dnf f-cb1sel "cb1 select" () 25 3) +(dnf f-cb2sel "cb2 select" () 22 3) +(dnf f-cb1incr "cb1 increment" (SIGNED) 19 6) +(dnf f-cb2incr "cb2 increment" (SIGNED) 13 6) +(dnf f-rc3 "row/colum context" () 7 1) + +; The following is just for a test +(dnf f-msysfrsr2 "sr2 for msys" () 19 4) +(dnf f-brc2 "b_r_c2" () 14 3) +(dnf f-ball2 "b_all2" () 15 1) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Enumerations Of Instruction Fields ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; insn-msys: bit 31. 1 for Morphosys Insns, 0 if not. +(define-normal-insn-enum insn-msys "msys enums" () MSYS_ f-msys + (NO YES) +) + +; insn-opc: bits 30 through 25 . Non-MorphoSys Instructions +; Note - the documentation is wrong for the encoding of the DBNZ +; instruction. It is actually 011110. See Issue 67699. +(define-normal-insn-enum insn-opc "opc enums" () OPC_ f-opc + (ADD ADDU SUB SUBU MUL - - - + AND OR XOR NAND NOR XNOR LDUI - + LSL LSR ASR - - - - - + BRLT BRLE BREQ JMP JAL BRNEQ DBNZ LOOP + LDW STW - - - - - - + - - - - - - - - + EI DI SI RETI BREAK IFLUSH - - + ) +) + +; insn-msopc: bits 30 through 26 . MorphoSys Instructions +(define-normal-insn-enum insn-msopc "msopc enums" () MSOPC_ f-msopc + (LDCTXT LDFB STFB FBCB MFBCB FBCCI FBRCI FBCRI + FBRRI MFBCCI MFBRCI MFBCRI MFBRRI FBCBDR RCFBCB MRCFBCB + CBCAST DUPCBCAST WFBI WFB RCRISC FBCBINC RCXMODE INTLVR + WFBINC MWFBINC WFBINCR MWFBINCR FBCBINCS MFBCBINCS FBCBINCRS MFBCBINCRS + - - - - - - - - + ) +) + +; insn-imm: bit 24. Immediate operand indicator. +(define-normal-insn-enum insn-imm "imm enums" () IMM_ f-imm + ; This bit specifies whether and immediate operand will be present. + ; It's 1 if there is, 0 if there is not. + (NO YES) +) +;;;;;;;;;;;;;;;; +;; Attributes ;; +;;;;;;;;;;;;;;;; + +; Might not need this. Keep if for the sim just in case. +;(define-attr +; (for insn) +; (type boolean) +; (name EXT-SKIP-INSN) +; (comment "instruction is a PAGE, LOADL or LOADH instruction") +;) + +(define-attr + (for insn) + (type boolean) + (name LOAD-DELAY) + (comment "insn has a load delay") +) + +(define-attr + (for insn) + (type boolean) + (name MEMORY-ACCESS) + (comment "insn performs a memory access") +) + +(define-attr + (for insn) + (type boolean) + (name AL-INSN) + (comment "insn is an arithmetic or logic insn.") +) + +(define-attr + (for insn) + (type boolean) + (name IO-INSN) + (comment "insn performs an I/O operation") +) + +(define-attr + (for insn) + (type boolean) + (name BR-INSN) + (comment "insn performs an I/O operation") +) + +(define-attr + (for insn) + (type boolean) + (name JAL-HAZARD) + (comment "insn has jal-like hazard") +) + +(define-pmacro (define-reg-use-attr regfield) + (define-attr + (for insn) + (type boolean) + (name (.sym "USES-" (.upcase regfield))) + (comment ("insn accesses register operand " regfield)))) + +(define-reg-use-attr "frdr") +(define-reg-use-attr "frdrrr") +(define-reg-use-attr "frsr1") +(define-reg-use-attr "frsr2") + + +; Might not need this. Keep it for the sim just in case. +(define-attr + (for insn) + (type boolean) + (name SKIPA) + (comment "instruction is a SKIP instruction") +) + + +;;;;;;;;;;;;;;;;;;;;; +;; Hardware Pieces ;; +;;;;;;;;;;;;;;;;;;;;; + +;(define-pmacro (build-reg-name n) (.splice (.str "$" n) n)) + +; These are the 16 registers that the chip has. In later versions +; where there will be more registers, this will need to be expanded. +; Note that there are two entries for the registers with two names. +(define-hardware + (name h-spr) + (comment "special-purpose registers") + (type register SI (16)) + (indices keyword "" (("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) ("fp" 12) + ("R13" 13) ("sp" 13) ("R14" 14) ("ra" 14) ("R15" 15) ("ira" 15))) +; (get (index) (and (raw-reg h-spr) #xffffffff)) +; (set (index value) (set (raw-reg h-spr) (and value #xffffffff))) +) + +; This is the program counter. +(dnh h-pc "program counter" (PC PROFILE) (pc) () () ()) + +(define-keyword + (name msys-syms) + (print-name h-nil) + (prefix "") + (values (DUP 1) (XX 0)) +) + +;;;;;;;;;;;;;; +;; Operands ;; +;;;;;;;;;;;;;; + +(define-operand (name frsr1) (comment "register") (attrs) + (type h-spr) (index f-sr1) ) +(define-operand (name frsr2) (comment "register") (attrs) + (type h-spr) (index f-sr2) ) +(define-operand (name frdr) (comment "register") (attrs) + (type h-spr) (index f-dr) ) +(define-operand (name frdrrr) (comment "register") (attrs) + (type h-spr) (index f-drrr) ) +(define-operand (name imm16) (comment "immediate value - sign extd") (attrs) + (type h-sint) (index f-imm16s) (handlers (parse "imm16") (print "dollarhex"))) +(define-operand (name imm16z) (comment "immediate value - zero extd") (attrs) + (type h-uint) (index f-imm16u) (handlers (parse "imm16") (print "dollarhex"))) +(define-operand (name imm16o) (comment "immediate value") (attrs PCREL-ADDR) + (type h-uint) (index f-imm16s) (handlers (parse "imm16") (print "pcrel"))) + +; Operands for MorphoSys Instructions + +(define-operand (name rc) (comment "rc") (attrs) + (type h-uint) (index f-rc) (handlers (parse "rc") (print "dollarhex"))) + +(define-operand (name rcnum) (comment "rcnum") (attrs) + (type h-uint) (index f-rcnum) (handlers (print "dollarhex"))) + +(define-operand (name contnum) (comment "context number") (attrs) + (type h-uint) (index f-contnum) (handlers (print "dollarhex"))) + +(define-operand (name rbbc) (comment "omega network configuration") (attrs) + (type h-uint) (index f-rbbc) (handlers (parse "rbbc") (print "dollarhex"))) + +(define-operand (name colnum) (comment "column number") (attrs) + (type h-uint) (index f-colnum) (handlers (print "dollarhex"))) + +(define-operand (name rownum) (comment "row number") (attrs) + (type h-uint) (index f-rownum) (handlers (print "dollarhex"))) + +(define-operand (name rownum1) (comment "row number") (attrs) + (type h-uint) (index f-rownum1) (handlers (print "dollarhex"))) + +(define-operand (name rownum2) (comment "row number") (attrs) + (type h-uint) (index f-rownum2) (handlers (print "dollarhex"))) + +(define-operand (name rc1) (comment "rc1") (attrs) + (type h-uint) (index f-rc1) (handlers (parse "rc") (print "dollarhex"))) + +(define-operand (name rc2) (comment "rc2") (attrs) + (type h-uint) (index f-rc2) (handlers (parse "rc") (print "dollarhex"))) + +(define-operand (name cbrb) (comment "data-bus orientation") (attrs) + (type h-uint) (index f-cbrb) (handlers (parse "cbrb") (print "dollarhex"))) + +(define-operand (name cell) (comment "cell") (attrs) + (type h-uint) (index f-cell) (handlers (print "dollarhex"))) + +(define-operand (name dup) (comment "dup") (attrs) + (type h-uint) (index f-dup) (handlers (parse "dup") (print "dollarhex"))) + +(define-operand (name ctxdisp) (comment "context displacement") (attrs) + (type h-uint) (index f-ctxdisp) (handlers (print "dollarhex"))) + +(define-operand (name fbdisp) (comment "frame buffer displacement") (attrs) + (type h-uint) (index f-fbdisp) (handlers (print "dollarhex"))) + +(define-operand (name type) (comment "type") (attrs) + (type h-uint) (index f-type) (handlers (parse "type") (print "dollarhex"))) + +(define-operand (name mask) (comment "mask") (attrs) + (type h-uint) (index f-mask) (handlers (print "dollarhex"))) + +(define-operand (name bankaddr) (comment "bank address") (attrs) + (type h-uint) (index f-bankaddr) (handlers (print "dollarhex"))) + +(define-operand (name incamt) (comment "increment amount") (attrs) + (type h-uint) (index f-incamt) (handlers (print "dollarhex"))) + +(define-operand (name xmode) (comment "xmode") (attrs) + (type h-uint) (index f-xmode) (handlers (parse "xmode") (print "dollarhex"))) + +(define-operand (name mask1) (comment "mask1") (attrs) + (type h-uint) (index f-mask1) (handlers (print "dollarhex"))) + +(define-operand (name ball) (comment "b_all") (attrs) + (type h-uint) (index f-ball) (handlers (parse "ball") (print "dollarhex"))) + +(define-operand (name brc) (comment "b_r_c") (attrs) + (type h-uint) (index f-brc) (handlers (print "dollarhex"))) + +(define-operand (name rda) (comment "rd") (attrs) + (type h-uint) (index f-rda) (handlers (print "dollarhex"))) + +(define-operand (name wr) (comment "wr") (attrs) + (type h-uint) (index f-wr) (handlers (print "dollarhex"))) + +(define-operand (name ball2) (comment "b_all2") (attrs) + (type h-uint) (index f-ball2) (handlers (parse "ball") (print "dollarhex"))) + +(define-operand (name brc2) (comment "b_r_c2") (attrs) + (type h-uint) (index f-brc2) (handlers (print "dollarhex"))) +(define-operand (name perm) (comment "perm") (attrs) + (type h-uint) (index f-perm) (handlers (print "dollarhex"))) +(define-operand (name a23) (comment "a23") (attrs) + (type h-uint) (index f-a23) (handlers (print "dollarhex"))) +(define-operand (name cr) (comment "c-r") (attrs) + (type h-uint) (index f-cr) (handlers (print "dollarhex"))) +(define-operand (name cbs) (comment "cbs") (attrs) + (type h-uint) (index f-cbs) (handlers (print "dollarhex"))) +(define-operand (name incr) (comment "incr") (attrs) + (type h-uint) (index f-incr) (handlers (print "dollarhex"))) +(define-operand (name length) (comment "length") (attrs) + (type h-uint) (index f-length) (handlers (print "dollarhex"))) +(define-operand (name cbx) (comment "cbx") (attrs) + (type h-uint) (index f-cbx) (handlers (print "dollarhex"))) +(define-operand (name ccb) (comment "ccb") (attrs) + (type h-uint) (index f-ccb) (handlers (print "dollarhex"))) +(define-operand (name cdb) (comment "cdb") (attrs) + (type h-uint) (index f-cdb) (handlers (print "dollarhex"))) + +; For the INTLVR insn +(define-operand (name mode) (comment "mode") (attrs) + (type h-uint) (index f-mode) (handlers (print "dollarhex"))) +(define-operand (name id) (comment "i/d") (attrs) + (type h-uint) (index f-id) (handlers (print "dollarhex"))) +(define-operand (name size) (comment "size") (attrs) + (type h-uint) (index f-size) (handlers (print "dollarhex"))) + +(define-operand (name fbincr) (comment "fb incr") (attrs) + (type h-uint) (index f-fbincr) (handlers (print "dollarhex"))) + +; For the ms2 insns +(define-operand (name loopsize) (comment "immediate value") + (attrs (MACH ms2) PCREL-ADDR) + (type h-uint) (index f-loopo) (handlers (parse "loopsize") (print "pcrel"))) +(define-operand (name imm16l) (comment "immediate value") + (attrs (MACH ms2)) + (type h-uint) (index f-imm16l) (handlers (print "dollarhex"))) +(define-operand (name rc3) (comment "rc3") (attrs (MACH ms2)) + (type h-uint) (index f-rc3) (handlers (parse "rc") (print "dollarhex"))) +(define-operand (name cb1sel) (comment "cb1sel") (attrs (MACH ms2)) + (type h-uint) (index f-cb1sel) (handlers (print "dollarhex"))) +(define-operand (name cb2sel) (comment "cb2sel") (attrs (MACH ms2)) + (type h-uint) (index f-cb2sel) (handlers (print "dollarhex"))) +(define-operand (name cb1incr) (comment "cb1incr") (attrs (MACH ms2)) + (type h-sint) (index f-cb1incr) (handlers (print "dollarhex"))) +(define-operand (name cb2incr) (comment "cb2incr") (attrs (MACH ms2)) + (type h-sint) (index f-cb2incr) (handlers (print "dollarhex"))) + +; Probaby won't need most of these. +(define-pmacro r0 (reg h-spr #x0)) +(define-pmacro r1 (reg h-spr #x01)) +(define-pmacro r2 (reg h-spr #x02)) +(define-pmacro r3 (reg h-spr #x03)) +(define-pmacro r4 (reg h-spr #x04)) +(define-pmacro r5 (reg h-spr #x05)) +(define-pmacro r6 (reg h-spr #x06)) +(define-pmacro r7 (reg h-spr #x07)) +(define-pmacro r8 (reg h-spr #x08)) +(define-pmacro r9 (reg h-spr #x09)) +(define-pmacro r10 (reg h-spr #xA)) +(define-pmacro r11 (reg h-spr #xB)) +(define-pmacro r12 (reg h-spr #xC)) +(define-pmacro fp (reg h-spr #xC)) +(define-pmacro r13 (reg h-spr #xD)) +(define-pmacro sp (reg h-spr #xD)) +(define-pmacro r14 (reg h-spr #xE)) +(define-pmacro ra (reg h-spr #xE)) +(define-pmacro r15 (reg h-spr #xF)) +(define-pmacro ira (reg h-spr #xF)) + +; delayed set +(define-pmacro (dset dest src) (set (delay 1 dest) src)) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Instructions As Defined In the MorphoRisc ISA Document ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Arithmetic Instructions + +(dni add "ADD DstReg, SrcReg1, SrcReg2" + (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2) + "add $frdrrr,$frsr1,$frsr2" + (+ MSYS_NO OPC_ADD IMM_NO frsr1 frsr2 frdrrr (f-uu12 0)) + (set frdrrr (add SI frsr1 frsr2)) + () +) + +(dni addu "ADDU DstReg, SrcReg1, SrcReg2" + (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2) + "addu $frdrrr,$frsr1,$frsr2" + (+ MSYS_NO OPC_ADDU IMM_NO frsr1 frsr2 frdrrr (f-uu12 0)) + (set frdrrr (add USI frsr1 frsr2)) + () +) + +(dni addi "ADDI DstReg, SrcReg1 UnsImm" + (AL-INSN USES-FRDR USES-FRSR1) + "addi $frdr,$frsr1,#$imm16" + (+ MSYS_NO OPC_ADD IMM_YES frsr1 frdr imm16) + (sequence((HI tmp)) + (set HI tmp (and imm16 #xffff)) + (set frdr (add SI frsr1 (ext SI tmp))) + ) + () +) + +(dni addui "ADDUI DstReg, SrcReg1, UnsImm" + (AL-INSN USES-FRDR USES-FRSR1) + "addui $frdr,$frsr1,#$imm16z" + (+ MSYS_NO OPC_ADDU IMM_YES frsr1 frdr imm16z) + (set frdr (add USI frsr1 (ext USI imm16z))) + () +) + +(dni sub "SUB DstReg, SrcReg1, SrcReg2" + (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2) + "sub $frdrrr,$frsr1,$frsr2" + (+ MSYS_NO OPC_SUB IMM_NO frsr1 frsr2 frdrrr (f-uu12 0)) + (set frdrrr (sub SI frsr1 frsr2)) + () +) + +(dni subu "SUBU DstReg, SrcReg1, SrcReg2" + (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2) + "subu $frdrrr,$frsr1,$frsr2" + (+ MSYS_NO OPC_SUBU IMM_NO frsr1 frsr2 frdrrr (f-uu12 0)) + (set frdrrr (sub USI frsr1 frsr2)) + () +) + +(dni subi "SUBI DstReg, SrcReg1, UnsImm" + (AL-INSN USES-FRDR USES-FRSR1) + "subi $frdr,$frsr1,#$imm16" + (+ MSYS_NO OPC_SUB IMM_YES frsr1 frdr imm16) + (sequence((HI tmp)) + (set HI tmp (and imm16 #xffff)) + (set frdr (sub SI frsr1 (ext SI tmp))) + ) + ;(set frdr (sub SI frsr1 (ext SI imm16))) + () +) + +(dni subui "SUBUI DstReg, SrcReg1, UnsImm" + (AL-INSN USES-FRDR USES-FRSR1) + "subui $frdr,$frsr1,#$imm16z" + (+ MSYS_NO OPC_SUBU IMM_YES frsr1 frdr imm16z) + (set frdr (sub USI frsr1 (ext USI imm16z))) + () +) + +(dni mul "MUL DstReg, SrcReg1, SrcReg2" + ((MACH ms1-003,ms2) AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2) + "mul $frdrrr,$frsr1,$frsr2" + (+ MSYS_NO OPC_MUL IMM_NO frsr1 frsr2 frdrrr (f-uu12 0)) + (sequence((HI op1) (HI op2)) + (set op1 (and frsr1 #xffff)) + (if (or (lt op1 (const -32768)) (gt op1 (const 32767))) + (error "operand out of range") + ) + (set op2 (and frsr2 #xffff)) + (if (or (lt op2 (const -32768)) (gt op2 (const 32767))) + (error "operand out of range") + ) + (set frdrrr (mul SI (ext SI op1) (ext SI op2))) + ) + () +) + +(dni muli "MULI DstReg, SrcReg1, UnsImm" + ((MACH ms1-003,ms2) AL-INSN USES-FRDR USES-FRSR1) + "muli $frdr,$frsr1,#$imm16" + (+ MSYS_NO OPC_MUL IMM_YES frsr1 frdr imm16) + (sequence((HI op1) (HI op2)) + (set op1 (and frsr1 #xffff)) + (if (or (lt op1 (const -32768)) (gt op1 (const 32767))) + (error "operand out of range") + ) + (set op2 (and imm16 #xffff)) + (if (eq op1 (const 0)) + (error "op1 is 0") + ) + (if (eq op2 (const 0)) + (error "op2 is 0") + ) + (set frdr (mul SI (ext SI op1) (ext SI op2))) + ) + () +) + +; Logical Instructions + +(dni and "AND DstReg, SrcReg1, SrcReg2" + (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2) + "and $frdrrr,$frsr1,$frsr2" + (+ MSYS_NO OPC_AND IMM_NO frsr1 frsr2 frdrrr (f-uu12 0)) + (set frdrrr (and frsr1 frsr2)) + () +) + +(dni andi "ANDI DstReg, SrcReg1, UnsImm" + (AL-INSN USES-FRDR USES-FRSR1) + "andi $frdr,$frsr1,#$imm16z" + (+ MSYS_NO OPC_AND IMM_YES frsr1 frdr imm16z) + (set frdr (and frsr1 (ext USI imm16z))) + () +) + +(dni or "OR DstReg, SrcReg1, SrcReg2" + (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2) + "or $frdrrr,$frsr1,$frsr2" + (+ MSYS_NO OPC_OR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0)) + (set frdrrr (or frsr1 frsr2)) + () +) + +(dni nop "nop" + () + "nop" + (+ MSYS_NO OPC_OR IMM_NO (f-uu24 0)) + (nop) + () +) + +(dni ori "ORI DstReg, SrcReg1, UnsImm" + (AL-INSN USES-FRDR USES-FRSR1) + "ori $frdr,$frsr1,#$imm16z" + (+ MSYS_NO OPC_OR IMM_YES frsr1 frdr imm16z) + (set frdr (or frsr1 (ext USI imm16z))) + () +) + +(dni xor "XOR DstReg, SrcReg1, SrcReg2" + (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2) + "xor $frdrrr,$frsr1,$frsr2" + (+ MSYS_NO OPC_XOR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0)) + (set frdrrr (xor frsr1 frsr2)) + () +) + +(dni xori "XORI DstReg, SrcReg1, UnsImm" + (AL-INSN USES-FRDR USES-FRSR1) + "xori $frdr,$frsr1,#$imm16z" + (+ MSYS_NO OPC_XOR IMM_YES frsr1 frdr imm16z) + (set frdr (xor frsr1 (ext USI imm16z))) + () +) + +(dni nand "NAND DstReg, SrcReg1, SrcReg2" + (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2) + "nand $frdrrr,$frsr1,$frsr2" + (+ MSYS_NO OPC_NAND IMM_NO frsr1 frsr2 frdrrr (f-uu12 0)) + (set frdrrr (inv (and frsr1 frsr2))) + () +) + +(dni nandi "NANDI DstReg, SrcReg1, UnsImm" + (AL-INSN USES-FRDR USES-FRSR1) + "nandi $frdr,$frsr1,#$imm16z" + (+ MSYS_NO OPC_NAND IMM_YES frsr1 frdr imm16z) + (set frdr (inv (and frsr1 (ext USI imm16z)))) + () +) + +(dni nor "NOR DstReg, SrcReg1, SrcReg2" + (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2) + "nor $frdrrr,$frsr1,$frsr2" + (+ MSYS_NO OPC_NOR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0)) + (set frdrrr (inv (or frsr1 frsr2))) + () +) + +(dni nori "NORI DstReg, SrcReg1, UnsImm" + (AL-INSN USES-FRDR USES-FRSR1) + "nori $frdr,$frsr1,#$imm16z" + (+ MSYS_NO OPC_NOR IMM_YES frsr1 frdr imm16z) + (set frdr (inv (or frsr1 (ext USI imm16z)))) + () +) + +(dni xnor "XNOR DstReg, SrcReg1, SrcReg2" + (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2) + "xnor $frdrrr,$frsr1,$frsr2" + (+ MSYS_NO OPC_XNOR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0)) + (set frdrrr (inv (xor frsr1 frsr2))) + () +) + +(dni xnori "XNORI DstReg, SrcReg1, UnsImm" + (AL-INSN USES-FRDR USES-FRSR1) + "xnori $frdr,$frsr1,#$imm16z" + (+ MSYS_NO OPC_XNOR IMM_YES frsr1 frdr imm16z) + (set frdr (inv (xor frsr1 (ext USI imm16z)))) + () +) + +(dni ldui "LDUI DstReg, UnsImm" + (AL-INSN USES-FRDR) + "ldui $frdr,#$imm16z" + (+ MSYS_NO OPC_LDUI IMM_YES (f-uu4b 0) frdr imm16z) + (set frdr (and (sll imm16z 16) #xffff0000)) + () +) + +; Shift Instructions + +(dni lsl "LSL DstReg, SrcReg1, SrcReg2" + (USES-FRDRRR USES-FRSR1 USES-FRSR2) + "lsl $frdrrr,$frsr1,$frsr2" + (+ MSYS_NO OPC_LSL IMM_NO frsr1 frsr2 frdrrr (f-uu12 0)) + (set frdrrr (sll frsr1 frsr2)) + () +) + +(dni lsli "LSLI DstReg, SrcReg1, UnsImm" + (USES-FRDR USES-FRSR1) + "lsli $frdr,$frsr1,#$imm16" + (+ MSYS_NO OPC_LSL IMM_YES frsr1 frdr imm16) + (set frdr (sll frsr1 imm16)) + () +) + +(dni lsr "LSR DstReg, SrcReg1, SrcReg2" + (USES-FRDRRR USES-FRSR1 USES-FRSR2) + "lsr $frdrrr,$frsr1,$frsr2" + (+ MSYS_NO OPC_LSR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0)) + (set frdrrr (srl frsr1 frsr2)) + () +) + +(dni lsri "LSRI DstReg, SrcReg1, UnsImm" + (USES-FRDR USES-FRSR1) + "lsri $frdr,$frsr1,#$imm16" + (+ MSYS_NO OPC_LSR IMM_YES frsr1 frdr imm16) + (set frdr (srl frsr1 imm16)) + () +) + +(dni asr "ASR DstReg, SrcReg1, SrcReg2" + (USES-FRDRRR USES-FRSR1 USES-FRSR2) + "asr $frdrrr,$frsr1,$frsr2" + (+ MSYS_NO OPC_ASR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0)) + (set frdrrr (sra frsr1 frsr2)) + () +) + +(dni asri "ASRI DstReg, SrcReg1, UnsImm" + (USES-FRDR USES-FRSR1) + "asri $frdr,$frsr1,#$imm16" + (+ MSYS_NO OPC_ASR IMM_YES frsr1 frdr imm16) + (set frdr (sra frsr1 imm16)) + () +) + +; Control Transfer Instructions + +(dni brlt "BRLT SrcReg1, SrcReg2, label" + (BR-INSN DELAY-SLOT USES-FRDRRR USES-FRSR1 USES-FRSR2) + "brlt $frsr1,$frsr2,$imm16o" + (+ MSYS_NO OPC_BRLT IMM_YES frsr1 frsr2 imm16o) + (sequence() + (if (lt USI frsr1 frsr2) + (dset pc (add pc (ext SI imm16o)))) + ) + () +) + +(dni brle "BRLE SrcReg1, SrcReg2, label" + (BR-INSN DELAY-SLOT USES-FRSR1 USES-FRSR2) + "brle $frsr1,$frsr2,$imm16o" + (+ MSYS_NO OPC_BRLE IMM_YES frsr1 frsr2 imm16o) + (sequence() + (if (le USI frsr1 frsr2) + (dset pc (add pc (ext SI imm16o)))) + ) + () +) + +(dni breq "BREQ SrcReg1, SrcReg2, label" + (BR-INSN DELAY-SLOT USES-FRSR1 USES-FRSR2) + "breq $frsr1,$frsr2,$imm16o" + (+ MSYS_NO OPC_BREQ IMM_YES frsr1 frsr2 imm16o) + (sequence() + (if (eq USI frsr1 frsr2) + (dset pc (add pc (ext SI imm16o)))) + ) + () +) + +(dni brne "BRNE SrcReg1, SrcReg2, label" + (BR-INSN DELAY-SLOT USES-FRSR1 USES-FRSR2) + "brne $frsr1,$frsr2,$imm16o" + (+ MSYS_NO OPC_BRNEQ IMM_YES frsr1 frsr2 imm16o) + (sequence() + (if (not (eq USI frsr1 frsr2)) + (dset pc (add pc (ext SI imm16o)))) + ) + () +) + +(dni jmp "JMP, label" + (DELAY-SLOT BR-INSN) + "jmp $imm16o" + (+ MSYS_NO OPC_JMP IMM_YES (f-uu4b 0) (f-uu4a 0) imm16o) + (dset pc (add pc (ext SI imm16o))) + () +) + +(dni jal "JAL DstReg, SrcReg1" + (BR-INSN DELAY-SLOT BR-INSN USES-FRDR USES-FRSR1 JAL-HAZARD) + "jal $frdrrr,$frsr1" + (+ MSYS_NO OPC_JAL IMM_NO frsr1 (f-uu4a 0) frdrrr (f-uu12 0)) + (sequence() + (if (eq frsr1 #x0) + (c-call VOID "do_syscall" pc) + (sequence() ; else part. Do non-syscall stuff here. + (dset frdrrr (add pc #x8)) + (dset pc frsr1) + ) + ) + ) + () +) + +(dni dbnz "DBNZ SrcReg1, label" + ((MACH ms1-003,ms2) BR-INSN DELAY-SLOT USES-FRSR1) + "dbnz $frsr1,$imm16o" + (+ MSYS_NO OPC_DBNZ IMM_YES frsr1 (f-uu4a 0) imm16o) + (sequence() + (if (not (eq USI frsr1 0)) + (dset pc (add pc (ext SI imm16o)))) + ) + () +) + +; Interrupt Control Instructions + +(dni ei "EI - Enable Interrupt Processing" + () + "ei" + (+ MSYS_NO OPC_EI IMM_NO (f-uu4b 0) (f-uu4a 0) (f-uu16 0)) + (c-call VOID "enable_interrupts") + () +) + +(dni di "DI - Disable Interrupt Processing" + () + "di" + (+ MSYS_NO OPC_DI IMM_NO (f-uu4b 0) (f-uu4a 0) (f-uu16 0)) + (c-call VOID "disable_interrupts") + () +) + +(dni si "SI - Send software Interrupt" + (DELAY-SLOT BR-INSN USES-FRDR) + "si $frdrrr" + (+ MSYS_NO OPC_SI IMM_NO (f-uu4b 0) (f-uu4a 0) frdrrr (f-uu12 0)) + ;(sequence() + ; (dset frdr (add pc #x4)) + ; (c-call VOID "do_syscall1" pc) + ; ; (dset pc frsr1) Do this later when we have the address. + ;) + (sequence() + (set frdrrr (add pc #x4)) + (c-call VOID "do_syscall" pc) + ; (set pc frsr1) Do this later when we have the address. + ) + () +) + +(dni reti "RETI SrcReg1" + (DELAY-SLOT BR-INSN USES-FRSR1 JAL-HAZARD) + "reti $frsr1" + (+ MSYS_NO OPC_RETI IMM_NO frsr1 (f-uu4a 0) (f-uu16 0)) + (sequence() + (c-call VOID "enable_interrupts") + (dset pc frsr1) + ) + () +) + +; Memory Access Instructions + +(dni ldw "LDW DstReg, SrcReg1, Imm" + (LOAD-DELAY MEMORY-ACCESS USES-FRDR USES-FRSR1) + "ldw $frdr,$frsr1,#$imm16" + (+ MSYS_NO OPC_LDW IMM_YES frsr1 frdr imm16) + (sequence((USI ea) (HI tmp)) + (set HI tmp (and imm16 #xffff)) + (set ea (and (add SI frsr1 (ext SI tmp)) #xfffffffc)) + (set frdr (mem SI ea)) + ) + () +) + +(dni stw "STW SrcReg2, SrcReg1, Imm" + (MEMORY-ACCESS USES-FRSR1 USES-FRSR2) + "stw $frsr2,$frsr1,#$imm16" + (+ MSYS_NO OPC_STW IMM_YES frsr1 frsr2 imm16) + (sequence((USI ea) (HI tmp)) + (set HI tmp (and imm16 #xffff)) + (set ea (and (add SI frsr1 (ext SI tmp)) #xfffffffc)) + (set (mem SI ea) frsr2) + ) + () +) + +; Break Instruction + +(dni break "BREAK" + () + "break" + (+ MSYS_NO OPC_BREAK (f-imm 0) (f-uu24 0)) + (c-call VOID "do_break" pc) + () +) + +; Cache Flush Instruction + +(dni iflush "IFLUSH" + ((MACH ms1-003,ms2)) + "iflush" + (+ MSYS_NO OPC_IFLUSH (f-imm 0) (f-uu24 0)) + (nop) + () +) + +; MorphoSys Instructions + +(dni ldctxt "LDCTXT SRC1, SRC2, r/c, r/c#, context#" + ((MACH ms1)) + "ldctxt $frsr1,$frsr2,#$rc,#$rcnum,#$contnum" + (+ MSYS_YES MSOPC_LDCTXT (f-uu-2-25 0) frsr1 frsr2 rc rcnum (f-uu-3-11 0) + contnum ) + (nop) + () +) + +(dni ldfb "LDFB SRC1, byte#" + ((MACH ms1)) + "ldfb $frsr1,$frsr2,#$imm16z" + (+ MSYS_YES MSOPC_LDFB (f-uu-2-25 0) frsr1 frsr2 imm16z) + (nop) + () +) + +(dni stfb "STFB SRC1, SRC2, byte " + ((MACH ms1)) + "stfb $frsr1,$frsr2,#$imm16z" + (+ MSYS_YES MSOPC_STFB (f-uu-2-25 0) frsr1 frsr2 imm16z) + (nop) + () +) + +(dni fbcb "FBCB SRC1, RT/BR1/BR2/CS, B_all, B_r_c, r/c, CB/RB, cell, dup, ctx_disp" + ((MACH ms1,ms1-003)) + "fbcb $frsr1,#$rbbc,#$ball,#$brc,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_FBCB rbbc frsr1 ball brc (f-uu-4-15 0) rc cbrb cell dup ctxdisp) + (nop) + () +) + +(dni mfbcb "MFBCB SRC1, RT/BR1/BR2/CS, SRC2, r/c, CB/RB, cell, dup, ctx_disp" + () + "mfbcb $frsr1,#$rbbc,$frsr2,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_MFBCB rbbc frsr1 frsr2 (f-uu-4-15 0) rc1 cbrb cell dup ctxdisp) + (nop) + () +) + +(dni fbcci "FBCCI SRC1, RT/BR1/BR2/CS, B_all, B_r_c, FB_disp, cell, dup, ctx_disp" + () + "fbcci $frsr1,#$rbbc,#$ball,#$brc,#$fbdisp,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_FBCCI rbbc frsr1 ball brc fbdisp cell dup ctxdisp) + (nop) + () +) + +(dni fbrci "FBRCI SRC1, RT/BR1/BR2/CS, B_all, B_r_c, FB_disp, cell, dup, ctx_disp" + () + "fbrci $frsr1,#$rbbc,#$ball,#$brc,#$fbdisp,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_FBRCI rbbc frsr1 ball brc fbdisp cell dup ctxdisp) + (nop) + () +) + +(dni fbcri "FBCRI SRC1, RT/BR1/BR2/CS, B_all, B_r_c, FB_disp, cell, dup, ctx_disp" + () + "fbcri $frsr1,#$rbbc,#$ball,#$brc,#$fbdisp,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_FBCRI rbbc frsr1 ball brc fbdisp cell dup ctxdisp) + (nop) + () +) + +(dni fbrri "FBRRI SRC1, RT/BR1/BR2/CS, B_all, B_r_c, FB_disp, cell, dup, ctx_disp" + () + "fbrri $frsr1,#$rbbc,#$ball,#$brc,#$fbdisp,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_FBRRI rbbc frsr1 ball brc fbdisp cell dup ctxdisp) + (nop) + () +) + +(dni mfbcci "MFBCCI SRC1, RT/BR1/BR2/CS, SRC2, FB_disp, cell, dup, ctx_disp" + () + "mfbcci $frsr1,#$rbbc,$frsr2,#$fbdisp,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_MFBCCI rbbc frsr1 frsr2 fbdisp cell dup ctxdisp) + (nop) + () +) + +(dni mfbrci "MFBRCI SRC1, RT/BR1/BR2/CS, SRC2, FB_disp, cell, dup, ctx_disp" + () + "mfbrci $frsr1,#$rbbc,$frsr2,#$fbdisp,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_MFBRCI rbbc frsr1 frsr2 fbdisp cell dup ctxdisp) + (nop) + () +) + +(dni mfbcri "MFBCRI SRC1, RT/BR1/BR2/CS, SRC2, FB_disp, cell, dup, ctx_disp" + () + "mfbcri $frsr1,#$rbbc,$frsr2,#$fbdisp,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_MFBCRI rbbc frsr1 frsr2 fbdisp cell dup ctxdisp) + (nop) + () +) + +(dni mfbrri "MFBRRI SRC1, RT/BR1/BR2/CS, SRC2, FB_disp, cell, dup, ctx_disp" + () + "mfbrri $frsr1,#$rbbc,$frsr2,#$fbdisp,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_MFBRRI rbbc frsr1 frsr2 fbdisp cell dup ctxdisp) + (nop) + () +) + +(dni fbcbdr "FBCBDR SRC1, RT/BR1/BR2/CS, SRC2, B_all, B_r_c, r/c, CB/RB, cell, dup, ctx_disp" + () + "fbcbdr $frsr1,#$rbbc,$frsr2,#$ball2,#$brc2,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_FBCBDR rbbc frsr1 frsr2 ball2 brc2 rc1 cbrb cell dup ctxdisp) + (nop) + () +) + +(dni rcfbcb "RCFBCB RT/BR1/BR2/CS, type, B_all, B_r_c, row#, r/c, CB/RB, cell, dup, ctx_disp" + () + "rcfbcb #$rbbc,#$type,#$ball,#$brc,#$rownum,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_RCFBCB rbbc (f-uu-2-23 0) type ball brc (f-uu-1-15 0) rownum rc1 cbrb cell dup ctxdisp) + (nop) + () +) + +(dni mrcfbcb "MRCFBCB SRC2, RT/BR1/BR2/CS, type, row#, r/c, CB/RB, cell, dup, ctx_disp" + () + "mrcfbcb $frsr2,#$rbbc,#$type,#$rownum,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_MRCFBCB rbbc (f-uu-2-23 0) type frsr2 (f-uu-1-15 0) rownum rc1 cbrb cell dup ctxdisp) + (nop) + () +) + +(dni cbcast "CBCAST mask, r/c, ctx_disp " + () + "cbcast #$mask,#$rc2,#$ctxdisp" + (+ MSYS_YES MSOPC_CBCAST mask (f-uu-3-9 0) rc2 ctxdisp) + (nop) + () +) + +(dni dupcbcast "DUPCBCAST mask, cell, r/c, ctx_disp " + () + "dupcbcast #$mask,#$cell,#$rc2,#$ctxdisp" + (+ MSYS_YES MSOPC_DUPCBCAST mask cell rc2 ctxdisp) + (nop) + () +) + +(dni wfbi "WFBI Bank_address, row#, cell, dup, ctx_disp " + () + "wfbi #$bankaddr,#$rownum1,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_WFBI bankaddr rownum1 cell dup ctxdisp) + (nop) + () +) + +;(dni wfb "WFB SRC1, SRC2, FB_disp, row#, ctx_disp" +; () +; "wfb $frsr1,$frsr2,#$fbdisp,#$rownum,#$ctxdisp" +; (+ MSYS_YES MSOPC_WFB (f-uu-2-25 0) frsr1 frsr2 fbdisp rownum (f-uu-1-6 0) ctxdisp) +; (nop) +; () +;) + +(dni wfb "WFB, DRC1,SRC2,FB_disp,row#,ctx_disp" + () + "wfb $frsr1,$frsr2,#$fbdisp,#$rownum2,#$ctxdisp" + (+ MSYS_YES MSOPC_WFB (f-uu-2-25 0) frsr1 frsr2 fbdisp rownum2 (f-uu-1-6 0) ctxdisp) + (nop) + () +) + + +(dni rcrisc "RCRISC DEST, RT/BR1/BR2/CS, SRC1, column#, r/c, CB/RB, cell, dup, ctx_disp" + () + "rcrisc $frdrrr,#$rbbc,$frsr1,#$colnum,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_RCRISC rbbc frsr1 (f-uu-1-19 0) colnum frdrrr rc1 cbrb cell dup ctxdisp) + (nop) + () +) + +(dni fbcbinc "FBCBINC SRC1, RT/BR1/BR2/CS, Incr_amount, r/c, CB/RB, cell, dup, ctx_disp " + () + "fbcbinc $frsr1,#$rbbc,#$incamt,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_FBCBINC rbbc frsr1 incamt rc1 cbrb cell dup ctxdisp) + (nop) + () +) + +(dni rcxmode "RCXMODE SRC2, rd, wr, xmode, mask, FB_disp, row#, r/c, ctx_disp" + () + "rcxmode $frsr2,#$rda,#$wr,#$xmode,#$mask1,#$fbdisp,#$rownum2,#$rc2,#$ctxdisp" + (+ MSYS_YES MSOPC_RCXMODE rda wr xmode mask1 frsr2 fbdisp rownum2 rc2 ctxdisp) + (nop) + () +) + +(dni interleaver "INTLVR ireg, mode, ireg, i/d, size" + () + "intlvr $frsr1,#$mode,$frsr2,#$id,#$size" + (+ MSYS_YES MSOPC_INTLVR mode frsr1 frsr2 (f-uu-1-15 0) id size) + (nop) + () +) + +;; Issue 66262: The documenatation gives the wrong order for +;; the arguments to the WFBINC instruction. +(dni wfbinc "WFBINC type, ccb/rcb, incr, all, c/r, length, rca_row, word, dup, ctxt_disp" + ((MACH ms1-003,ms2)) + "wfbinc #$rda,#$wr,#$fbincr,#$ball,#$colnum,#$length,#$rownum1,#$rownum2,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_WFBINC rda wr fbincr ball colnum length rownum1 rownum2 dup ctxdisp) + (nop) + () +) + +(dni mwfbinc "MWFBINC mreg, type, ccb/rcb, incr, length, rca_row, word, dup, ctxt_disp" + ((MACH ms1-003,ms2)) + "mwfbinc $frsr2,#$rda,#$wr,#$fbincr,#$length,#$rownum1,#$rownum2,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_MWFBINC rda wr fbincr frsr2 length rownum1 rownum2 dup ctxdisp) + (nop) + () +) + +(dni wfbincr "WFBINCR ireg, type, ccb/rcb, all, c/r, length, rca_row, word, dup, ctxt_disp" + ((MACH ms1-003,ms2)) + "wfbincr $frsr1,#$rda,#$wr,#$ball,#$colnum,#$length,#$rownum1,#$rownum2,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_WFBINCR rda wr frsr1 ball colnum length rownum1 rownum2 dup ctxdisp) + (nop) + () +) + +(dni mwfbincr "MWFBINCR ireg, mreg, type, ccb/rcb, length, rca_row, word, dup, ctxt_disp" + ((MACH ms1-003,ms2)) + "mwfbincr $frsr1,$frsr2,#$rda,#$wr,#$length,#$rownum1,#$rownum2,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_MWFBINCR rda wr frsr1 frsr2 length rownum1 rownum2 dup ctxdisp) + (nop) + () +) + +(dni fbcbincs "FBCBINCS perm, all, c/r, cbs, incr, ccb/rcb, cdb/rdb, word, dup, ctxt_disp" + ((MACH ms1-003,ms2)) + "fbcbincs #$perm,#$a23,#$cr,#$cbs,#$incr,#$ccb,#$cdb,#$rownum2,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_FBCBINCS perm a23 cr cbs incr ccb cdb rownum2 dup ctxdisp) + (nop) + () +) + +(dni mfbcbincs "MFBCBINCS ireg, perm, cbs, incr, ccb/rcb, cdb/rdb, word, dup, ctxt_disp" + ((MACH ms1-003,ms2)) + "mfbcbincs $frsr1,#$perm,#$cbs,#$incr,#$ccb,#$cdb,#$rownum2,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_MFBCBINCS perm frsr1 cbs incr ccb cdb rownum2 dup ctxdisp) + (nop) + () +) + +(dni fbcbincrs "FBCBINCRS ireg, perm, all, c/r, cbs, ccb/rcb, cdb/rdb, word, dup, ctxt_disp" + ((MACH ms1-003,ms2)) + "fbcbincrs $frsr1,#$perm,#$ball,#$colnum,#$cbx,#$ccb,#$cdb,#$rownum2,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_FBCBINCRS perm frsr1 ball colnum (f-uu-1-15 0) cbx ccb cdb rownum2 dup ctxdisp) + (nop) + () +) + +(dni mfbcbincrs "MFBCBINCRS ireg, mreg, perm, cbs, ccb/rcb, cdb/rdb, word, dup, ctxt_disp" + ((MACH ms1-003,ms2)) + "mfbcbincrs $frsr1,$frsr2,#$perm,#$cbx,#$ccb,#$cdb,#$rownum2,#$dup,#$ctxdisp" + (+ MSYS_YES MSOPC_MFBCBINCRS perm frsr1 frsr2 (f-uu-1-15 0) cbx ccb cdb rownum2 dup ctxdisp) + (nop) + () +) + +; MS2 instructions +(dni loop "LOOP SrcReg1, label" + ((MACH ms2) DELAY-SLOT USES-FRSR1) + "loop $frsr1,$loopsize" + (+ MSYS_NO OPC_LOOP IMM_NO frsr1 (f-uu4a 0) (f-uu8 0) loopsize) + (nop) ;; to be filled in + () +) + +(dni loopi "LOOPI niter, label" + ((MACH ms2) DELAY-SLOT) + "loopi #$imm16l,$loopsize" + (+ MSYS_NO OPC_LOOP IMM_YES imm16l loopsize) + (nop) ;; to be filled in + () +) + +(dni dfbc "dfbc cb1sel,cb2sel,cb1inc,cb2inc,dr/c,cr/c,ctxdisp" + ((MACH ms2)) + "dfbc #$cb1sel,#$cb2sel,#$cb1incr,#$cb2incr,#$rc3,#$rc2,#$ctxdisp" + (+ MSYS_YES MSOPC_LDCTXT cb1sel cb2sel cb1incr cb2incr rc3 rc2 ctxdisp) + (nop) + () +) + +(dni dwfb "dwfb cb1sel,cb2sel,cb1inc,cb2inc,cr/c,ctxdisp" + ((MACH ms2)) + "dwfb #$cb1sel,#$cb2sel,#$cb1incr,#$cb2incr,#$rc2,#$ctxdisp" + (+ MSYS_YES MSOPC_LDFB cb1sel cb2sel cb1incr cb2incr (f-uu1 0) rc2 ctxdisp) + (nop) + () +) + +(dni fbwfb "fbwfb cb1sel,cb2sel,cb1inc,cb2inc,r0/1,cr/c,ctxdisp" + ((MACH ms2)) + "fbwfb #$cb1sel,#$cb2sel,#$cb1incr,#$cb2incr,#$rc3,#$rc2,#$ctxdisp" + (+ MSYS_YES MSOPC_STFB cb1sel cb2sel cb1incr cb2incr rc3 rc2 ctxdisp) + (nop) + () +) + +(dni dfbr "dfbr cb1sel,cb2sel,reg,W/O1,W/O2,mode,cr/c,ctxdisp" + ((MACH ms2) USES-FRSR2) + "dfbr #$cb1sel,#$cb2sel,$frsr2,#$length,#$rownum1,#$rownum2,#$rc2,#$ctxdisp" + (+ MSYS_YES MSOPC_FBCB cb1sel cb2sel frsr2 length rownum1 rownum2 rc2 ctxdisp) + (nop) + () +) diff --git a/cpu/mt.opc b/cpu/mt.opc new file mode 100644 index 00000000000..3da6d0ea963 --- /dev/null +++ b/cpu/mt.opc @@ -0,0 +1,472 @@ +/* Morpho Technologies mRISC opcode support, for GNU Binutils. -*- C -*- + Copyright 2001, 2007, 2008, 2009 Free Software Foundation, Inc. + + Contributed by Red Hat Inc; developed under contract from + Morpho Technologies. + + 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. */ + + +/* Each section is delimited with start and end markers. + + <arch>-opc.h additions use: "-- opc.h" + <arch>-opc.c additions use: "-- opc.c" + <arch>-asm.c additions use: "-- asm.c" + <arch>-dis.c additions use: "-- dis.c" + <arch>-ibd.h additions use: "-- ibd.h" */ + +/* -- opc.h */ + +/* Check applicability of instructions against machines. */ +#define CGEN_VALIDATE_INSN_SUPPORTED + +/* Allows reason codes to be output when assembler errors occur. */ +#define CGEN_VERBOSE_ASSEMBLER_ERRORS + +/* Override disassembly hashing - there are variable bits in the top + byte of these instructions. */ +#define CGEN_DIS_HASH_SIZE 8 +#define CGEN_DIS_HASH(buf, value) (((* (unsigned char *) (buf)) >> 5) % CGEN_DIS_HASH_SIZE) + +#define CGEN_ASM_HASH_SIZE 127 +#define CGEN_ASM_HASH(insn) mt_asm_hash (insn) + +extern unsigned int mt_asm_hash (const char *); + +extern int mt_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *); + + +/* -- opc.c */ +#include "safe-ctype.h" + +/* Special check to ensure that instruction exists for given machine. */ + +int +mt_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn) +{ + int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH); + + /* No mach attribute? Assume it's supported for all machs. */ + if (machs == 0) + return 1; + + return ((machs & cd->machs) != 0); +} + +/* A better hash function for instruction mnemonics. */ + +unsigned int +mt_asm_hash (const char* insn) +{ + unsigned int hash; + const char* m = insn; + + for (hash = 0; *m && ! ISSPACE (*m); m++) + hash = (hash * 23) ^ (0x1F & TOLOWER (*m)); + + /* printf ("%s %d\n", insn, (hash % CGEN_ASM_HASH_SIZE)); */ + + return hash % CGEN_ASM_HASH_SIZE; +} + + +/* -- asm.c */ +/* Range checking for signed numbers. Returns 0 if acceptable + and 1 if the value is out of bounds for a signed quantity. */ + +static int +signed_out_of_bounds (long val) +{ + if ((val < -32768) || (val > 32767)) + return 1; + return 0; +} + +static const char * +parse_loopsize (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + void *arg) +{ + signed long * valuep = (signed long *) arg; + const char *errmsg; + bfd_reloc_code_real_type code = BFD_RELOC_NONE; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + /* Is it a control transfer instructions? */ + if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_LOOPSIZE) + { + code = BFD_RELOC_MT_PCINSN8; + errmsg = cgen_parse_address (cd, strp, opindex, code, + & result_type, & value); + *valuep = value; + return errmsg; + } + + abort (); +} + +static const char * +parse_imm16 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + void *arg) +{ + signed long * valuep = (signed long *) arg; + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_reloc_code_real_type code = BFD_RELOC_NONE; + bfd_vma value; + + /* Is it a control transfer instructions? */ + if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16O) + { + code = BFD_RELOC_16_PCREL; + errmsg = cgen_parse_address (cd, strp, opindex, code, + & result_type, & value); + if (errmsg == NULL) + { + if (signed_out_of_bounds (value)) + errmsg = _("Operand out of range. Must be between -32768 and 32767."); + } + *valuep = value; + return errmsg; + } + + /* If it's not a control transfer instruction, then + we have to check for %OP relocating operators. */ + if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16L) + ; + else if (strncmp (*strp, "%hi16", 5) == 0) + { + *strp += 5; + code = BFD_RELOC_HI16; + } + else if (strncmp (*strp, "%lo16", 5) == 0) + { + *strp += 5; + code = BFD_RELOC_LO16; + } + + /* If we found a %OP relocating operator, then parse it as an address. + If not, we need to parse it as an integer, either signed or unsigned + depending on which operand type we have. */ + if (code != BFD_RELOC_NONE) + { + /* %OP relocating operator found. */ + errmsg = cgen_parse_address (cd, strp, opindex, code, + & result_type, & value); + if (errmsg == NULL) + { + switch (result_type) + { + case (CGEN_PARSE_OPERAND_RESULT_NUMBER): + if (code == BFD_RELOC_HI16) + value = (value >> 16) & 0xFFFF; + else if (code == BFD_RELOC_LO16) + value = value & 0xFFFF; + else + errmsg = _("Biiiig Trouble in parse_imm16!"); + break; + + case (CGEN_PARSE_OPERAND_RESULT_QUEUED): + /* No special processing for this case. */ + break; + + default: + errmsg = _("The percent-operator's operand is not a symbol"); + break; + } + } + *valuep = value; + } + else + { + /* Parse hex values like 0xffff as unsigned, and sign extend + them manually. */ + int parse_signed = (opindex == (CGEN_OPERAND_TYPE)MT_OPERAND_IMM16); + + if ((*strp)[0] == '0' + && ((*strp)[1] == 'x' || (*strp)[1] == 'X')) + parse_signed = 0; + + /* No relocating operator. Parse as an number. */ + if (parse_signed) + { + /* Parse as as signed integer. */ + + errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep); + + if (errmsg == NULL) + { +#if 0 + /* Manual range checking is needed for the signed case. */ + if (*valuep & 0x8000) + value = 0xffff0000 | *valuep; + else + value = *valuep; + + if (signed_out_of_bounds (value)) + errmsg = _("Operand out of range. Must be between -32768 and 32767."); + /* Truncate to 16 bits. This is necessary + because cgen will have sign extended *valuep. */ + *valuep &= 0xFFFF; +#endif + } + } + else + { + /* MT_OPERAND_IMM16Z. Parse as an unsigned integer. */ + errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, (unsigned long *) valuep); + + if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16 + && *valuep >= 0x8000 + && *valuep <= 0xffff) + *valuep -= 0x10000; + } + } + + return errmsg; +} + + +static const char * +parse_dup (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg = NULL; + + if (strncmp (*strp, "dup", 3) == 0 || strncmp (*strp, "DUP", 3) == 0) + { + *strp += 3; + *valuep = 1; + } + else if (strncmp (*strp, "xx", 2) == 0 || strncmp (*strp, "XX", 2) == 0) + { + *strp += 2; + *valuep = 0; + } + else + errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); + + return errmsg; +} + + +static const char * +parse_ball (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg = NULL; + + if (strncmp (*strp, "all", 3) == 0 || strncmp (*strp, "ALL", 3) == 0) + { + *strp += 3; + *valuep = 1; + } + else if (strncmp (*strp, "one", 3) == 0 || strncmp (*strp, "ONE", 3) == 0) + { + *strp += 3; + *valuep = 0; + } + else + errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); + + return errmsg; +} + +static const char * +parse_xmode (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg = NULL; + + if (strncmp (*strp, "pm", 2) == 0 || strncmp (*strp, "PM", 2) == 0) + { + *strp += 2; + *valuep = 1; + } + else if (strncmp (*strp, "xm", 2) == 0 || strncmp (*strp, "XM", 2) == 0) + { + *strp += 2; + *valuep = 0; + } + else + errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); + + return errmsg; +} + +static const char * +parse_rc (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg = NULL; + + if (strncmp (*strp, "r", 1) == 0 || strncmp (*strp, "R", 1) == 0) + { + *strp += 1; + *valuep = 1; + } + else if (strncmp (*strp, "c", 1) == 0 || strncmp (*strp, "C", 1) == 0) + { + *strp += 1; + *valuep = 0; + } + else + errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); + + return errmsg; +} + +static const char * +parse_cbrb (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg = NULL; + + if (strncmp (*strp, "rb", 2) == 0 || strncmp (*strp, "RB", 2) == 0) + { + *strp += 2; + *valuep = 1; + } + else if (strncmp (*strp, "cb", 2) == 0 || strncmp (*strp, "CB", 2) == 0) + { + *strp += 2; + *valuep = 0; + } + else + errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); + + return errmsg; +} + +static const char * +parse_rbbc (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg = NULL; + + if (strncmp (*strp, "rt", 2) == 0 || strncmp (*strp, "RT", 2) == 0) + { + *strp += 2; + *valuep = 0; + } + else if (strncmp (*strp, "br1", 3) == 0 || strncmp (*strp, "BR1", 3) == 0) + { + *strp += 3; + *valuep = 1; + } + else if (strncmp (*strp, "br2", 3) == 0 || strncmp (*strp, "BR2", 3) == 0) + { + *strp += 3; + *valuep = 2; + } + else if (strncmp (*strp, "cs", 2) == 0 || strncmp (*strp, "CS", 2) == 0) + { + *strp += 2; + *valuep = 3; + } + else + errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); + + return errmsg; +} + +static const char * +parse_type (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + const char *errmsg = NULL; + + if (strncmp (*strp, "odd", 3) == 0 || strncmp (*strp, "ODD", 3) == 0) + { + *strp += 3; + *valuep = 0; + } + else if (strncmp (*strp, "even", 4) == 0 || strncmp (*strp, "EVEN", 4) == 0) + { + *strp += 4; + *valuep = 1; + } + else if (strncmp (*strp, "oe", 2) == 0 || strncmp (*strp, "OE", 2) == 0) + { + *strp += 2; + *valuep = 2; + } + else + errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); + + if ((errmsg == NULL) && (*valuep == 3)) + errmsg = _("invalid operand. type may have values 0,1,2 only."); + + return errmsg; +} + +/* -- dis.c */ +static void print_dollarhex (CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int); +static void print_pcrel (CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int); + +static void +print_dollarhex (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + disassemble_info *info = (disassemble_info *) dis_info; + + info->fprintf_func (info->stream, "$%lx", value); + + if (0) + print_normal (cd, dis_info, value, attrs, pc, length); +} + +static void +print_pcrel (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + print_address (cd, dis_info, value + pc, attrs, pc, length); +} + +/* -- */ + + + + + diff --git a/cpu/sh.cpu b/cpu/sh.cpu new file mode 100644 index 00000000000..d9ece1a03ef --- /dev/null +++ b/cpu/sh.cpu @@ -0,0 +1,369 @@ +; Hitachi SH architecture description. -*- Scheme -*- +; +; Copyright 2000, 2001, 2007, 2009 Free Software Foundation, Inc. +; +; Contributed by Red Hat Inc; developed under contract from Hitachi +; Semiconductor (America) Inc. +; +; 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 sh) + (comment "Hitachi SuperH (SH)") + (insn-lsb0? #t) + (machs sh2 sh3 sh3e sh4 sh5) + (isas compact media) +) + + +; Instruction sets. + +(define-isa + (name media) + (comment "SHmedia 32-bit instruction set") + (base-insn-bitsize 32) +) + +(define-isa + (name compact) + (comment "SHcompact 16-bit instruction set") + (base-insn-bitsize 16) +) + + +; CPU family. + +(define-cpu + (name sh64) + (comment "SH 64-bit family") + (endian either) + (word-bitsize 32) +) + + +(define-mach + (name sh2) + (comment "SH-2 CPU core") + (cpu sh64) + (isas compact) +) + +(define-mach + (name sh3) + (comment "SH-3 CPU core") + (cpu sh64) + (isas compact) +) + +(define-mach + (name sh3e) + (comment "SH-3e CPU core") + (cpu sh64) + (isas compact) +) + +(define-mach + (name sh4) + (comment "SH-4 CPU core") + (cpu sh64) + (isas compact) +) + +(define-mach + (name sh5) + (comment "SH-5 CPU core") + (cpu sh64) + (isas compact media) +) + +(define-model + (name sh5) + (comment "SH-5 reference implementation") + (mach sh5) + (unit u-exec "Execution unit" () + 1 1 ; issue done + () () () ()) +) + +; Hardware elements. + +(define-hardware + (name h-pc) + (comment "Program counter") + (attrs PC (ISA compact,media)) + (type pc UDI) + (get () (raw-reg h-pc)) + (set (newval) (sequence () + (set (raw-reg h-ism) (and newval 1)) + (set (raw-reg h-pc) (and newval (inv UDI 1))))) +) + +(define-pmacro (-build-greg-name n) ((.sym r n) n)) + +(define-hardware + (name h-gr) + (comment "General purpose integer registers") + (attrs (ISA media,compact)) + (type register DI (64)) + (indices keyword "" (.map -build-greg-name (.iota 64))) + (get (index) + (if DI (eq index 63) + (const 0) + (raw-reg h-gr index))) + (set (index newval) + (if (ne index 63) + (set (raw-reg h-gr index) newval) + (nop))) +) + +(define-hardware + (name h-grc) + (comment "General purpose integer registers (SHcompact view)") + (attrs VIRTUAL (ISA compact)) + (type register SI (16)) + (indices keyword "" (.map -build-greg-name (.iota 16))) + (get (index) + (and (raw-reg h-gr index) (zext DI #xFFFFFFFF))) + (set (index newval) + (set (raw-reg h-gr index) (ext DI newval))) +) + +(define-pmacro (-build-creg-name n) ((.sym cr n) n)) + +(define-hardware + (name h-cr) + (comment "Control registers") + (attrs (ISA media)) + (type register DI (64)) + (indices keyword "" (.map -build-creg-name (.iota 64))) + (get (index) + (if DI (eq index 0) + (zext DI (reg h-sr)) + (raw-reg h-cr index))) + (set (index newval) + (if (eq index 0) + (set (reg h-sr) newval) + (set (raw-reg h-cr index) newval))) +) + +(define-hardware + (name h-sr) + (comment "Status register") + (attrs (ISA compact,media)) + (type register SI) +) + +(define-hardware + (name h-fpscr) + (comment "Floating point status and control register") + (attrs (ISA compact,media)) + (type register SI) +) + +(define-hardware + (name h-frbit) + (comment "Floating point register file bit") + (attrs (ISA media,compact) VIRTUAL) + (type register BI) + (get () (and (srl (reg h-sr) 14) 1)) + (set (newvalue) (set (reg h-sr) (or (and (reg h-sr) (inv (sll 1 14))) (sll SI newvalue 14)))) +) + +(define-hardware + (name h-szbit) + (comment "Floating point transfer size bit") + (attrs (ISA media,compact) VIRTUAL) + (type register BI) + (get () (and (srl (reg h-sr) 13) 1)) + (set (newvalue) (set (reg h-sr) (or (and (reg h-sr) (inv (sll 1 13))) (sll SI newvalue 13)))) +) + +(define-hardware + (name h-prbit) + (comment "Floating point precision bit") + (attrs (ISA media,compact) VIRTUAL) + (type register BI) + (get () (and (srl (reg h-sr) 12) 1)) + (set (newvalue) (set (reg h-sr) (or (and (reg h-sr) (inv (sll 1 12))) (sll SI newvalue 12)))) +) + +(define-hardware + (name h-sbit) + (comment "Multiply-accumulate saturation flag") + (attrs (ISA compact) VIRTUAL) + (type register BI) + (get () (and (srl (reg h-sr) 1) 1)) + (set (newvalue) (set (reg h-sr) (or (and (reg h-sr) (inv 2)) (sll SI newvalue 1)))) +) + +(define-hardware + (name h-mbit) + (comment "Divide-step M flag") + (attrs (ISA compact) VIRTUAL) + (type register BI) + (get () (and (srl (reg h-sr) 9) 1)) + (set (newvalue) (set (reg h-sr) (or (and (reg h-sr) (inv (sll 1 9))) (sll SI newvalue 9)))) +) + +(define-hardware + (name h-qbit) + (comment "Divide-step Q flag") + (attrs (ISA compact) VIRTUAL) + (type register BI) + (get () (and (srl (reg h-sr) 8) 1)) + (set (newvalue) (set (reg h-sr) (or (and (reg h-sr) (inv (sll 1 8))) (sll SI newvalue 8)))) +) + +(define-pmacro (-build-freg-name n) ((.sym fr n) n)) + +(define-hardware + (name h-fr) + (comment "Single precision floating point registers") + (attrs (ISA media,compact)) + (type register SF (64)) + (indices keyword "" (.map -build-freg-name (.iota 64))) +) + + +(define-pmacro (-build-fpair-name n) ((.sym fp n) n)) + +(define-hardware + (name h-fp) + (comment "Single precision floating point register pairs") + (attrs (ISA media,compact)) + (type register DF (32)) + (indices keyword "" (.map -build-fpair-name (.iota 32))) +) + +(define-pmacro (-build-fvec-name n) ((.sym fv n) n)) + +(define-hardware + (name h-fv) + (comment "Single precision floating point vectors") + (attrs VIRTUAL (ISA media,compact)) + (type register SF (16)) + (indices keyword "" (.map -build-fvec-name (.iota 16))) + ; Mask with $F to ensure 0 <= index < 15. + (get (index) (reg h-fr (mul (and UQI index 15) 4))) + (set (index newval) (set (reg h-fr (mul (and UQI index 15) 4)) newval)) +) + +(define-hardware + (name h-fmtx) + (comment "Single precision floating point matrices") + (attrs VIRTUAL (ISA media)) + (type register SF (4)) + (indices keyword "" ((mtrx0 0) (mtrx1 1) (mtrx2 2) (mtrx3 3))) + ; Mask with $3 to ensure 0 <= index < 4. + (get (index) (reg h-fr (mul (and UQI index 3) 16))) + (set (index newval) (set (reg h-fr (mul (and UQI index 3) 16)) newval)) +) + +(define-pmacro (-build-dreg-name n) ((.sym dr n) n)) + +(define-hardware + (name h-dr) + (comment "Double precision floating point registers") + (attrs (ISA media,compact) VIRTUAL) + (type register DF (32)) + (indices keyword "" (.map -build-dreg-name (.iota 64))) + (get (index) + (subword DF + (or + (sll DI (zext DI (subword SI (reg h-fr index) 0)) 32) + (zext DI (subword SI (reg h-fr (add index 1)) 0))) 0)) + (set (index newval) + (sequence () + (set (reg h-fr index) + (subword SF (subword SI newval 0) 0)) + (set (reg h-fr (add index 1)) + (subword SF (subword SI newval 1) 0)))) +) + +(define-hardware + (name h-tr) + (comment "Branch target registers") + (attrs (ISA media)) + (type register DI (8)) + (indices keyword "" ((tr0 0) (tr1 1) (tr2 2) (tr3 3) (tr4 4) (tr5 5) (tr6 6) (tr7 7))) +) + +(define-hardware + (name h-endian) + (comment "Current endian mode") + (attrs (ISA compact,media) VIRTUAL) + (type register BI) + (get () (c-call BI "sh64_endian")) + (set (newval) (error "cannot alter target byte order mid-program")) +) + +(define-hardware + (name h-ism) + (comment "Current instruction set mode") + (attrs (ISA compact,media)) + (type register BI) + (get () (raw-reg h-ism)) + (set (newval) (error "cannot set ism directly")) +) + + +; Operands. + +(dnop endian "Endian mode" ((ISA compact,media)) h-endian f-nil) +(dnop ism "Instruction set mode" ((ISA compact,media)) h-ism f-nil) + +; Universally useful macros. + +; A pmacro for use in semantic bodies of unimplemented insns. +(define-pmacro (unimp mnemonic) (nop)) + +; Join 2 ints together in natural bit order. +(define-pmacro (-join-si s1 s0) + (or (sll (zext DI s1) 32) + (zext DI s0))) + +; Join 4 half-ints together in natural bit order. +(define-pmacro (-join-hi h3 h2 h1 h0) + (or (sll (zext DI h3) 48) + (or (sll (zext DI h2) 32) + (or (sll (zext DI h1) 16) + (zext DI h0))))) + +; Join 8 quarter-ints together in natural bit order. +(define-pmacro (-join-qi b7 b6 b5 b4 b3 b2 b1 b0) + (or (sll (zext DI b7) 56) + (or (sll (zext DI b6) 48) + (or (sll (zext DI b5) 40) + (or (sll (zext DI b4) 32) + (or (sll (zext DI b3) 24) + (or (sll (zext DI b2) 16) + (or (sll (zext DI b1) 8) + (zext DI b0))))))))) + + +; Include the two instruction set descriptions from their respective +; source files. + +(if (keep-isa? (compact)) + (include "sh64-compact.cpu")) + +(if (keep-isa? (media)) + (include "sh64-media.cpu")) diff --git a/cpu/sh.opc b/cpu/sh.opc new file mode 100644 index 00000000000..364fcccf647 --- /dev/null +++ b/cpu/sh.opc @@ -0,0 +1,77 @@ +/* SHmedia opcode support. -*- C -*- + + Copyright 2000, 2005, 2007, 2009 Free Software Foundation, Inc. + + Contributed by Red Hat Inc; developed under contract from Hitachi + Semiconductor (America) Inc. + + 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. */ + + +/* This file is an addendum to sh-media.cpu. Heavy use of C code isn't + appropriate in .cpu files, so it resides here. This especially applies + to assembly/disassembly where parsing/printing can be quite involved. + Such things aren't really part of the specification of the cpu, per se, + so .cpu files provide the general framework and .opc files handle the + nitty-gritty details as necessary. + + Each section is delimited with start and end markers. + + <arch>-opc.h additions use: "-- opc.h" + <arch>-opc.c additions use: "-- opc.c" + <arch>-asm.c additions use: "-- asm.c" + <arch>-dis.c additions use: "-- dis.c" + <arch>-ibd.h additions use: "-- ibd.h" */ + +/* -- opc.h */ + +/* Allows reason codes to be output when assembler errors occur. */ +#define CGEN_VERBOSE_ASSEMBLER_ERRORS + +/* Override disassembly hashing - there are variable bits in the top + byte of these instructions. */ +#define CGEN_DIS_HASH_SIZE 8 +#define CGEN_DIS_HASH(buf,value) (((* (unsigned char*) (buf)) >> 6) % CGEN_DIS_HASH_SIZE) + +/* -- asm.c */ + +static const char * +parse_fsd (CGEN_CPU_DESC cd, + const char ** strp, + int opindex, + long * valuep) +{ + abort (); +} + +/* -- dis.c */ + +static void +print_likely (CGEN_CPU_DESC cd, + void * dis_info, + long value, + unsigned int attrs, + bfd_vma pc, + int length) +{ + disassemble_info *info = (disassemble_info *) dis_info; + + (*info->fprintf_func) (info->stream, (value) ? "/l" : "/u"); +} + +/* -- */ diff --git a/cpu/sh64-compact.cpu b/cpu/sh64-compact.cpu new file mode 100644 index 00000000000..5b1b8633028 --- /dev/null +++ b/cpu/sh64-compact.cpu @@ -0,0 +1,1748 @@ +; Hitachi SHcompact instruction set description. -*- Scheme -*- +; +; Copyright 2000, 2007, 2009 Free Software Foundation, Inc. +; +; Contributed by Red Hat Inc; developed under contract from Hitachi +; Semiconductor (America) Inc. +; +; 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. + +; dshcf -- define-normal-sh-compact-field + +(define-pmacro (dshcf xname xcomment ignored xstart xlength) + (dnf xname xcomment ((ISA compact)) xstart xlength)) + +; dshcop -- define-normal-sh-compact-operand + +(define-pmacro (dshcop xname xcomment ignored xhardware xfield) + (dnop xname xcomment ((ISA compact)) xhardware xfield)) + + +; SHcompact-specific attributes. + +(define-attr + (for insn) + (type boolean) + (name ILLSLOT) + (comment "instruction may not appear in a delay slot") +) + +(define-attr + (for insn) + (type boolean) + (name FP-INSN) + (comment "floating point instruction") +) + +(define-keyword + (name frc-names) + (attrs (ISA compact)) + (print-name h-frc) + (values (fr0 0) (fr1 1) (fr2 2) (fr3 3) (fr4 4) (fr5 5) + (fr6 6) (fr7 7) (fr8 8) (fr9 9) (fr10 10) (fr11 11) + (fr12 12) (fr13 13) (fr14 14) (fr15 15)) +) + +(define-keyword + (name drc-names) + (attrs (ISA compact)) + (print-name h-drc) + (values (dr0 0) (dr2 2) (dr4 4) (dr6 6) (dr8 8) (dr10 10) (dr12 12) (dr14 14)) +) + +(define-keyword + (name xf-names) + (attrs (ISA compact)) + (print-name h-xf) + (values (xf0 0) (xf1 1) (xf2 2) (xf3 3) (xf4 4) (xf5 5) + (xf6 6) (xf7 7) (xf8 8) (xf9 9) (xf10 10) (xf11 11) + (xf12 12) (xf13 13) (xf14 14) (xf15 15)) +) + +; Hardware specific to the SHcompact mode. + +(define-pmacro (front) (mul 16 frbit)) +(define-pmacro (back) (mul 16 (not frbit))) + +(define-hardware + (name h-frc) + (comment "Single precision floating point registers") + (attrs VIRTUAL (ISA compact)) + (indices extern-keyword frc-names) + (type register SF (16)) + (get (index) (reg h-fr (add (front) index))) + (set (index newval) (set (reg h-fr (add (front) index)) newval)) +) + +(define-hardware + (name h-drc) + (comment "Double precision floating point registers") + (attrs VIRTUAL (ISA compact)) + (indices extern-keyword drc-names) + (type register DF (8)) + (get (index) (reg h-dr (add (front) index))) + (set (index newval) (set (reg h-dr (add (front) index)) newval)) +) + +(define-hardware + (name h-xf) + (comment "Extended single precision floating point registers") + (attrs VIRTUAL (ISA compact)) + (indices extern-keyword xf-names) + (type register SF (16)) + (get (index) (reg h-fr (add (back) index))) + (set (index newval) (set (reg h-fr (add (back) index)) newval)) +) + +(define-hardware + (name h-xd) + (comment "Extended double precision floating point registers") + (attrs VIRTUAL (ISA compact)) + (indices extern-keyword frc-names) + (type register DF (8)) + (get (index) (reg h-dr (add (back) index))) + (set (index newval) (set (reg h-dr (add (back) index)) newval)) +) + +(define-hardware + (name h-fvc) + (comment "Single precision floating point vectors") + (attrs VIRTUAL (ISA compact)) + (indices keyword "" ((fv0 0) (fv4 4) (fv8 8) (fv12 12))) + (type register SF (4)) + (get (index) (reg h-fr (add (front) index))) + (set (index newval) (set (reg h-fr (add (front) index)) newval)) +) + +(define-hardware + (name h-fpccr) + (comment "SHcompact floating point status/control register") + (attrs VIRTUAL (ISA compact)) + (type register SI) + (get () (or (or (or (raw-reg h-fpscr) (sll SI prbit 19)) (sll SI szbit 20)) (sll SI frbit 21))) + (set (newvalue) (sequence () + (set (reg h-fpscr) newvalue) + (set prbit (and (srl newvalue 19) 1)) + (set szbit (and (srl newvalue 20) 1)) + (set frbit (and (srl newvalue 21) 1)))) +) + +(define-hardware + (name h-gbr) + (comment "Global base register") + (attrs VIRTUAL (ISA compact)) + (type register SI) + (get () (subword SI (raw-reg h-gr 16) 1)) + (set (newval) (set (raw-reg h-gr 16) (ext DI newval))) +) + +(define-hardware + (name h-pr) + (comment "Procedure link register") + (attrs VIRTUAL (ISA compact)) + (type register SI) + (get () (subword SI (raw-reg h-gr 18) 1)) + (set (newval) (set (raw-reg h-gr 18) (ext DI newval))) +) + +(define-hardware + (name h-macl) + (comment "Multiple-accumulate low register") + (attrs VIRTUAL (ISA compact)) + (type register SI) + (get () (subword SI (raw-reg h-gr 17) 1)) + (set (newval) (set (raw-reg h-gr 17) (-join-si (subword SI (raw-reg h-gr 17) 0) newval))) +) + +(define-hardware + (name h-mach) + (comment "Multiply-accumulate high register") + (attrs VIRTUAL (ISA compact)) + (type register SI) + (get () (subword SI (raw-reg h-gr 17) 0)) + (set (newval) (set (raw-reg h-gr 17) (-join-si newval (subword SI (raw-reg h-gr 17) 1)))) +) + +(define-hardware + (name h-tbit) + (comment "Condition code flag") + (attrs VIRTUAL (ISA compact)) + (type register BI) + (get () (and BI (raw-reg h-gr 19) 1)) + (set (newval) (set (raw-reg h-gr 19) (or (and (raw-reg h-gr 19) (inv DI 1)) (zext DI newval)))) +) + + +(dshcf f-op4 "Opcode (4 bits)" () 15 4) +(dshcf f-op8 "Opcode (8 bits)" () 15 8) +(dshcf f-op16 "Opcode (16 bits)" () 15 16) + +(dshcf f-sub4 "Sub opcode (4 bits)" () 3 4) +(dshcf f-sub8 "Sub opcode (8 bits)" () 7 8) +(dshcf f-sub10 "Sub opcode (10 bits)" () 9 10) + +(dshcf f-rn "Register selector n" () 11 4) +(dshcf f-rm "Register selector m" () 7 4) + +(dshcf f-8-1 "One bit at bit 8" () 8 1) + +(df f-disp8 "Displacement (8 bits)" ((ISA compact) PCREL-ADDR) 7 8 INT + ((value pc) (sra SI value 1)) + ((value pc) (add SI (sll SI value 1) (add pc 4)))) + +(df f-disp12 "Displacement (12 bits)" ((ISA compact) PCREL-ADDR) 11 12 INT + ((value pc) (sra SI value 1)) + ((value pc) (add SI (sll SI value 1) (add pc 4)))) + +(dshcf f-imm8 "Immediate (8 bits)" () 7 8) +(dshcf f-imm4 "Immediate (4 bits)" () 3 4) + +(df f-imm4x2 "Immediate (4 bits)" ((ISA compact)) 3 4 UINT + ((value pc) (srl SI value 1)) + ((value pc) (sll SI value 1))) + +(df f-imm4x4 "Immediate (4 bits)" ((ISA compact)) 3 4 UINT + ((value pc) (srl SI value 2)) + ((value pc) (sll SI value 2))) + +(df f-imm8x2 "Immediate (8 bits)" ((ISA compact)) 7 8 UINT + ((value pc) (sra SI value 1)) + ((value pc) (sll SI value 1))) + +(df f-imm8x4 "Immediate (8 bits)" ((ISA compact)) 7 8 UINT + ((value pc) (sra SI value 2)) + ((value pc) (sll SI value 2))) + +(df f-dn "Double selector n" ((ISA compact)) 11 3 UINT + ((value pc) (srl SI value 1)) + ((value pc) (sll SI value 1))) + +(df f-dm "Double selector m" ((ISA compact)) 7 3 UINT + ((value pc) (srl SI value 1)) + ((value pc) (sll SI value 1))) + +(df f-vn "Vector selector n" ((ISA compact)) 11 2 UINT + ((value pc) (srl SI value 2)) + ((value pc) (sll SI value 2))) + +(df f-vm "Vector selector m" ((ISA compact)) 9 2 UINT + ((value pc) (srl SI value 2)) + ((value pc) (sll SI value 2))) + +(df f-xn "Extended selector n" ((ISA compact)) 11 3 UINT + ((value pc) (srl SI value 1)) + ((value pc) (add SI (sll SI value 1) 1))) + +(df f-xm "Extended selector m" ((ISA compact)) 7 3 UINT + ((value pc) (srl SI value 1)) + ((value pc) (add SI (sll SI value 1) 1))) + + +; Operands. + +(dshcop rm "Left general purpose register" () h-grc f-rm) +(dshcop rn "Right general purpose register" () h-grc f-rn) +(dshcop r0 "Register 0" () h-grc 0) + +(dshcop frn "Single precision register" () h-frc f-rn) +(dshcop frm "Single precision register" () h-frc f-rm) + +(dshcop fvn "Left floating point vector" () h-fvc f-vn) +(dshcop fvm "Right floating point vector" () h-fvc f-vm) + +(dshcop drn "Left double precision register" () h-drc f-dn) +(dshcop drm "Right double precision register" () h-drc f-dm) + +(dshcop imm4 "Immediate value (4 bits)" () h-sint f-imm4) +(dshcop imm8 "Immediate value (8 bits)" () h-sint f-imm8) +(dshcop uimm8 "Immediate value (8 bits unsigned)" () h-uint f-imm8) + +(dshcop imm4x2 "Immediate value (4 bits, 2x scale)" () h-uint f-imm4x2) +(dshcop imm4x4 "Immediate value (4 bits, 4x scale)" () h-uint f-imm4x4) +(dshcop imm8x2 "Immediate value (8 bits, 2x scale)" () h-uint f-imm8x2) +(dshcop imm8x4 "Immediate value (8 bits, 4x scale)" () h-uint f-imm8x4) + +(dshcop disp8 "Displacement (8 bits)" () h-iaddr f-disp8) +(dshcop disp12 "Displacement (12 bits)" () h-iaddr f-disp12) + +(dshcop rm64 "Register m (64 bits)" () h-gr f-rm) +(dshcop rn64 "Register n (64 bits)" () h-gr f-rn) + +(dshcop gbr "Global base register" () h-gbr f-nil) +(dshcop pr "Procedure link register" () h-pr f-nil) + +(dshcop fpscr "Floating point status/control register" () h-fpccr f-nil) + +(dshcop tbit "Condition code flag" () h-tbit f-nil) +(dshcop sbit "Multiply-accumulate saturation flag" () h-sbit f-nil) +(dshcop mbit "Divide-step M flag" () h-mbit f-nil) +(dshcop qbit "Divide-step Q flag" () h-qbit f-nil) +(dshcop fpul "Floating point ???" () h-fr 32) + +(dshcop frbit "Floating point register bank bit" () h-frbit f-nil) +(dshcop szbit "Floating point transfer size bit" () h-szbit f-nil) +(dshcop prbit "Floating point precision bit" () h-prbit f-nil) + +(dshcop macl "Multiply-accumulate low register" () h-macl f-nil) +(dshcop mach "Multiply-accumulate high register" () h-mach f-nil) + + +(define-operand (name fsdm) (comment "bar") + (attrs (ISA compact)) (type h-frc) (index f-rm) (handlers (parse "fsd"))) + +(define-operand (name fsdn) (comment "bar") + (attrs (ISA compact)) (type h-frc) (index f-rn)) + + +; Cover macro to dni to indicate these are all SHcompact instructions. +; dshmi: define-normal-sh-compact-insn + +(define-pmacro (dshci xname xcomment xattrs xsyntax xformat xsemantics) + (define-insn + (name (.sym xname -compact)) + (comment xcomment) + (.splice attrs (.unsplice xattrs) (ISA compact)) + (syntax xsyntax) + (format xformat) + (semantics xsemantics))) + +(define-pmacro (dr operand) (reg h-dr (index-of operand))) +(define-pmacro (xd x) (reg h-xd (and (index-of x) (inv QI 1)))) + +(dshci add "Add" + () + "add $rm, $rn" + (+ (f-op4 3) rn rm (f-sub4 12)) + (set rn (add rn rm))) + +(dshci addi "Add immediate" + () + "add #$imm8, $rn" + (+ (f-op4 7) rn imm8) + (set rn (add rn (ext SI (and QI imm8 255))))) + +(dshci addc "Add with carry" + () + "addc $rm, $rn" + (+ (f-op4 3) rn rm (f-sub4 14)) + (sequence ((BI flag)) + (set flag (add-cflag rn rm tbit)) + (set rn (addc rn rm tbit)) + (set tbit flag))) + +(dshci addv "Add with overflow" + () + "addv $rm, $rn" + (+ (f-op4 3) rn rm (f-sub4 15)) + (sequence ((BI t)) + (set t (add-oflag rn rm 0)) + (set rn (add rn rm)) + (set tbit t))) + +(dshci and "Bitwise AND" + () + "and $rm64, $rn64" + (+ (f-op4 2) rn64 rm64 (f-sub4 9)) + (set rn64 (and rm64 rn64))) + +(dshci andi "Bitwise AND immediate" + () + "and #$uimm8, r0" + (+ (f-op8 #xc9) uimm8) + (set r0 (and r0 (zext DI uimm8)))) + +(dshci andb "Bitwise AND memory byte" + () + "and.b #$imm8, @(r0, gbr)" + (+ (f-op8 #xcd) imm8) + (sequence ((DI addr) (UQI data)) + (set addr (add r0 gbr)) + (set data (and (mem UQI addr) imm8)) + (set (mem UQI addr) data))) + +(dshci bf "Conditional branch" + () + "bf $disp8" + (+ (f-op8 #x8b) disp8) + (if (not tbit) + (set pc disp8))) + +(dshci bfs "Conditional branch with delay slot" + () + "bf/s $disp8" + (+ (f-op8 #x8f) disp8) + (if (not tbit) + (delay 1 (set pc disp8)))) + +(dshci bra "Branch" + () + "bra $disp12" + (+ (f-op4 10) disp12) + (delay 1 (set pc disp12))) + +(dshci braf "Branch far" + () + "braf $rn" + (+ (f-op4 0) rn (f-sub8 35)) + (delay 1 (set pc (add (ext DI rn) (add pc 4))))) + +(dshci brk "Breakpoint" + () + "brk" + (+ (f-op16 59)) + (c-call "sh64_break" pc)) + +(dshci bsr "Branch to subroutine" + () + "bsr $disp12" + (+ (f-op4 11) disp12) + (delay 1 (sequence () + (set pr (add pc 4)) + (set pc disp12)))) + +(dshci bsrf "Branch to far subroutine" + () + "bsrf $rn" + (+ (f-op4 0) rn (f-sub8 3)) + (delay 1 (sequence () + (set pr (add pc 4)) + (set pc (add (ext DI rn) (add pc 4)))))) + +(dshci bt "Conditional branch" + () + "bt $disp8" + (+ (f-op8 #x89) disp8) + (if tbit + (set pc disp8))) + +(dshci bts "Conditional branch with delay slot" + () + "bt/s $disp8" + (+ (f-op8 #x8d) disp8) + (if tbit + (delay 1 (set pc disp8)))) + +(dshci clrmac "Clear MACL and MACH" + () + "clrmac" + (+ (f-op16 40)) + (sequence () + (set macl 0) + (set mach 0))) + +(dshci clrs "Clear S-bit" + () + "clrs" + (+ (f-op16 72)) + (set sbit 0)) + +(dshci clrt "Clear T-bit" + () + "clrt" + (+ (f-op16 8)) + (set tbit 0)) + +(dshci cmpeq "Compare if equal" + () + "cmp/eq $rm, $rn" + (+ (f-op4 3) rn rm (f-sub4 0)) + (set tbit (eq rm rn))) + +(dshci cmpeqi "Compare if equal (immediate)" + () + "cmp/eq #$imm8, r0" + (+ (f-op8 #x88) imm8) + (set tbit (eq r0 (ext SI (and QI imm8 255))))) + +(dshci cmpge "Compare if greater than or equal" + () + "cmp/ge $rm, $rn" + (+ (f-op4 3) rn rm (f-sub4 3)) + (set tbit (ge rn rm))) + +(dshci cmpgt "Compare if greater than" + () + "cmp/gt $rm, $rn" + (+ (f-op4 3) rn rm (f-sub4 7)) + (set tbit (gt rn rm))) + +(dshci cmphi "Compare if greater than (unsigned)" + () + "cmp/hi $rm, $rn" + (+ (f-op4 3) rn rm (f-sub4 6)) + (set tbit (gtu rn rm))) + +(dshci cmphs "Compare if greater than or equal (unsigned)" + () + "cmp/hs $rm, $rn" + (+ (f-op4 3) rn rm (f-sub4 2)) + (set tbit (geu rn rm))) + +(dshci cmppl "Compare if greater than zero" + () + "cmp/pl $rn" + (+ (f-op4 4) rn (f-sub8 21)) + (set tbit (gt rn 0))) + +(dshci cmppz "Compare if greater than or equal zero" + () + "cmp/pz $rn" + (+ (f-op4 4) rn (f-sub8 17)) + (set tbit (ge rn 0))) + +(dshci cmpstr "Compare bytes" + () + "cmp/str $rm, $rn" + (+ (f-op4 2) rn rm (f-sub4 12)) + (sequence ((BI t) (SI temp)) + (set temp (xor rm rn)) + (set t (eq (and temp #xff000000) 0)) + (set t (or (eq (and temp #xff0000) 0) t)) + (set t (or (eq (and temp #xff00) 0) t)) + (set t (or (eq (and temp #xff) 0) t)) + (set tbit (if BI (gtu t 0) 1 0)))) + +(dshci div0s "Initialise divide-step state for signed division" + () + "div0s $rm, $rn" + (+ (f-op4 2) rn rm (f-sub4 7)) + (sequence () + (set qbit (srl rn 31)) + (set mbit (srl rm 31)) + (set tbit (if BI (eq (srl rm 31) (srl rn 31)) 0 1)))) + +(dshci div0u "Initialise divide-step state for unsigned division" + () + "div0u" + (+ (f-op16 25)) + (sequence () + (set tbit 0) + (set qbit 0) + (set mbit 0))) + +(dshci div1 "Divide step" + () + "div1 $rm, $rn" + (+ (f-op4 3) rn rm (f-sub4 4)) + (sequence ((BI oldq) (SI tmp0) (UQI tmp1)) + (set oldq qbit) + (set qbit (srl rn 31)) + (set rn (or (sll rn 1) (zext SI tbit))) + (if (not oldq) + (if (not mbit) + (sequence () + (set tmp0 rn) + (set rn (sub rn rm)) + (set tmp1 (gtu rn tmp0)) + (if (not qbit) + (set qbit (if BI tmp1 1 0)) + (set qbit (if BI (eq tmp1 0) 1 0)))) + (sequence () + (set tmp0 rn) + (set rn (add rn rm)) + (set tmp1 (ltu rn tmp0)) + (if (not qbit) + (set qbit (if BI (eq tmp1 0) 1 0)) + (set qbit (if BI tmp1 1 0))))) + (if (not mbit) + (sequence () + (set tmp0 rn) + (set rn (add rm rn)) + (set tmp1 (ltu rn tmp0)) + (if (not qbit) + (set qbit (if BI tmp1 1 0)) + (set qbit (if BI (eq tmp1 0) 1 0)))) + (sequence () + (set tmp0 rn) + (set rn (sub rn rm)) + (set tmp1 (gtu rn tmp0)) + (if (not qbit) + (set qbit (if BI (eq tmp1 0) 1 0)) + (set qbit (if BI tmp1 1 0)))))) + (set tbit (if BI (eq qbit mbit) 1 0)))) + +(dshci dmulsl "Multiply long (signed)" + () + "dmuls.l $rm, $rn" + (+ (f-op4 3) rn rm (f-sub4 13)) + (sequence ((DI result)) + (set result (mul (ext DI rm) (ext DI rn))) + (set mach (subword SI result 0)) + (set macl (subword SI result 1)))) + +(dshci dmulul "Multiply long (unsigned)" + () + "dmulu.l $rm, $rn" + (+ (f-op4 3) rn rm (f-sub4 5)) + (sequence ((DI result)) + (set result (mul (zext DI rm) (zext DI rn))) + (set mach (subword SI result 0)) + (set macl (subword SI result 1)))) + +(dshci dt "Decrement and set" + () + "dt $rn" + (+ (f-op4 4) rn (f-sub8 16)) + (sequence () + (set rn (sub rn 1)) + (set tbit (eq rn 0)))) + +(dshci extsb "Sign extend byte" + () + "exts.b $rm, $rn" + (+ (f-op4 6) rn rm (f-sub4 14)) + (set rn (ext SI (subword QI rm 3)))) + +(dshci extsw "Sign extend word" + () + "exts.w $rm, $rn" + (+ (f-op4 6) rn rm (f-sub4 15)) + (set rn (ext SI (subword HI rm 1)))) + +(dshci extub "Zero extend byte" + () + "extu.b $rm, $rn" + (+ (f-op4 6) rn rm (f-sub4 12)) + (set rn (zext SI (subword QI rm 3)))) + +(dshci extuw "Zero etxend word" + () + "extu.w $rm, $rn" + (+ (f-op4 6) rn rm (f-sub4 13)) + (set rn (zext SI (subword HI rm 1)))) + +(dshci fabs "Floating point absolute" + (FP-INSN) + "fabs $fsdn" + (+ (f-op4 15) fsdn (f-sub8 #x5d)) + (if prbit + (set (dr fsdn) (c-call DF "sh64_fabsd" (dr fsdn))) + (set fsdn (c-call SF "sh64_fabss" fsdn)))) + +(dshci fadd "Floating point add" + (FP-INSN) + "fadd $fsdm, $fsdn" + (+ (f-op4 15) fsdn fsdm (f-sub4 0)) + (if prbit + (set (dr fsdn) (c-call DF "sh64_faddd" (dr fsdm) (dr fsdn))) + (set fsdn (c-call SF "sh64_fadds" fsdm fsdn)))) + +(dshci fcmpeq "Floating point compare equal" + (FP-INSN) + "fcmp/eq $fsdm, $fsdn" + (+ (f-op4 15) fsdn fsdm (f-sub4 4)) + (if prbit + (set tbit (c-call BI "sh64_fcmpeqd" (dr fsdm) (dr fsdn))) + (set tbit (c-call BI "sh64_fcmpeqs" fsdm fsdn)))) + +(dshci fcmpgt "Floating point compare greater than" + (FP-INSN) + "fcmp/gt $fsdm, $fsdn" + (+ (f-op4 15) fsdn fsdm (f-sub4 5)) + (if prbit + (set tbit (c-call BI "sh64_fcmpgtd" (dr fsdn) (dr fsdm))) + (set tbit (c-call BI "sh64_fcmpgts" fsdn fsdm)))) + +(dshci fcnvds "Floating point convert (double to single)" + (FP-INSN) + "fcnvds $drn, fpul" + (+ (f-op4 15) drn (f-8-1 10) (f-sub8 #xbd)) + (set fpul (c-call SF "sh64_fcnvds" drn))) + +(dshci fcnvsd "Floating point convert (single to double)" + (FP-INSN) + "fcnvsd fpul, $drn" + (+ (f-op4 15) drn (f-8-1 0) (f-sub8 #xad)) + (set drn (c-call DF "sh64_fcnvsd" fpul))) + +(dshci fdiv "Floating point divide" + (FP-INSN) + "fdiv $fsdm, $fsdn" + (+ (f-op4 15) fsdn fsdm (f-sub4 3)) + (if prbit + (set (dr fsdn) (c-call DF "sh64_fdivd" (dr fsdn) (dr fsdm))) + (set fsdn (c-call SF "sh64_fdivs" fsdn fsdm)))) + +(dshci fipr "Floating point inner product" + (FP-INSN) + "fipr $fvm, $fvn" + (+ (f-op4 15) fvn fvm (f-sub8 #xed)) + (sequence ((QI m) (QI n) (SF res)) + (set m (index-of fvm)) + (set n (index-of fvn)) + (set res (c-call SF "sh64_fmuls" fvm fvn)) + (set res (c-call SF "sh64_fadds" res (c-call SF "sh64_fmuls" (reg h-frc (add m 1)) (reg h-frc (add n 1))))) + (set res (c-call SF "sh64_fadds" res (c-call SF "sh64_fmuls" (reg h-frc (add m 2)) (reg h-frc (add n 2))))) + (set res (c-call SF "sh64_fadds" res (c-call SF "sh64_fmuls" (reg h-frc (add m 3)) (reg h-frc (add n 3))))) + (set (reg h-frc (add n 3)) res))) + +(dshci flds "Floating point load status register" + (FP-INSN) + "flds $frn" + (+ (f-op4 15) frn (f-sub8 #x1d)) + (set fpul frn)) + +(dshci fldi0 "Floating point load immediate 0.0" + (FP-INSN) + "fldi0 $frn" + (+ (f-op4 15) frn (f-sub8 #x8d)) + (set frn (c-call SF "sh64_fldi0"))) + +(dshci fldi1 "Floating point load immediate 1.0" + (FP-INSN) + "fldi1 $frn" + (+ (f-op4 15) frn (f-sub8 #x9d)) + (set frn (c-call SF "sh64_fldi1"))) + +(dshci float "Floating point integer conversion" + (FP-INSN) + "float fpul, $fsdn" + (+ (f-op4 15) fsdn (f-sub8 #x2d)) + (if prbit + (set (dr fsdn) (c-call DF "sh64_floatld" fpul)) + (set fsdn (c-call SF "sh64_floatls" fpul)))) + +(dshci fmac "Floating point multiply and accumulate" + (FP-INSN) + "fmac fr0, $frm, $frn" + (+ (f-op4 15) frn frm (f-sub4 14)) + (set frn (c-call SF "sh64_fmacs" (reg h-frc 0) frm frn))) + +(define-pmacro (even x) (eq (and x 1) 0)) +(define-pmacro (odd x) (eq (and x 1) 1)) +(define-pmacro (extd x) (odd (index-of x))) + +(dshci fmov1 "Floating point move (register to register)" + (FP-INSN) + "fmov $frm, $frn" + (+ (f-op4 15) frn frm (f-sub4 12)) + (if (not szbit) + ; single precision operation + (set frn frm) + ; double or extended operation + (if (extd frm) + (if (extd frn) + (set (xd frn) (xd frm)) + (set (dr frn) (xd frm))) + (if (extd frn) + (set (xd frn) (dr frm)) + (set (dr frn) (dr frm)))))) + +(dshci fmov2 "Floating point load" + (FP-INSN) + "fmov @$rm, $frn" + (+ (f-op4 15) frn rm (f-sub4 8)) + (if (not szbit) + ; single precision operation + (set frn (mem SF rm)) + ; double or extended operation + (if (extd frn) + (set (xd frn) (mem DF rm)) + (set (dr frn) (mem DF rm))))) + +(dshci fmov3 "Floating point load (post-increment)" + (FP-INSN) + "fmov @${rm}+, frn" + (+ (f-op4 15) frn rm (f-sub4 9)) + (if (not szbit) + ; single precision operation + (sequence () + (set frn (mem SF rm)) + (set rm (add rm 4))) + ; double or extended operation + (sequence () + (if (extd frn) + (set (xd frn) (mem DF rm)) + (set (dr frn) (mem DF rm))) + (set rm (add rm 8))))) + +(dshci fmov4 "Floating point load (register/register indirect)" + (FP-INSN) + "fmov @(r0, $rm), $frn" + (+ (f-op4 15) frn rm (f-sub4 6)) + (if (not szbit) + ; single precision operation + (set frn (mem SF (add r0 rm))) + ; double or extended operation + (if (extd frn) + (set (xd frn) (mem DF (add r0 rm))) + (set (dr frn) (mem DF (add r0 rm)))))) + +(dshci fmov5 "Floating point store" + (FP-INSN) + "fmov $frm, @$rn" + (+ (f-op4 15) rn frm (f-sub4 10)) + (if (not szbit) + ; single precision operation + (set (mem SF rn) frm) + ; double or extended operation + (if (extd frm) + (set (mem DF rn) (xd frm)) + (set (mem DF rn) (dr frm))))) + +(dshci fmov6 "Floating point store (pre-decrement)" + (FP-INSN) + "fmov $frm, @-$rn" + (+ (f-op4 15) rn frm (f-sub4 11)) + (if (not szbit) + ; single precision operation + (sequence () + (set rn (sub rn 4)) + (set (mem SF rn) frm)) + ; double or extended operation + (sequence () + (set rn (sub rn 8)) + (if (extd frm) + (set (mem DF rn) (xd frm)) + (set (mem DF rn) (dr frm)))))) + +(dshci fmov7 "Floating point store (register/register indirect)" + (FP-INSN) + "fmov $frm, @(r0, $rn)" + (+ (f-op4 15) rn frm (f-sub4 7)) + (if (not szbit) + ; single precision operation + (set (mem SF (add r0 rn)) frm) + ; double or extended operation + (if (extd frm) + (set (mem DF (add r0 rn)) (xd frm)) + (set (mem DF (add r0 rn)) (dr frm))))) + +(dshci fmul "Floating point multiply" + (FP-INSN) + "fmul $fsdm, $fsdn" + (+ (f-op4 15) fsdn fsdm (f-sub4 2)) + (if prbit + (set (dr fsdn) (c-call DF "sh64_fmuld" (dr fsdm) (dr fsdn))) + (set fsdn (c-call SF "sh64_fmuls" fsdm fsdn)))) + +(dshci fneg "Floating point negate" + (FP-INSN) + "fneg $fsdn" + (+ (f-op4 15) fsdn (f-sub8 #x4d)) + (if prbit + (set (dr fsdn) (c-call DF "sh64_fnegd" (dr fsdn))) + (set fsdn (c-call SF "sh64_fnegs" fsdn)))) + +(dshci frchg "Toggle floating point register banks" + (FP-INSN) + "frchg" + (+ (f-op16 #xfbfd)) + (set frbit (not frbit))) + +(dshci fschg "Set size of floating point transfers" + (FP-INSN) + "fschg" + (+ (f-op16 #xf3fd)) + (set szbit (not szbit))) + +(dshci fsqrt "Floating point square root" + (FP-INSN) + "fsqrt $fsdn" + (+ (f-op4 15) fsdn (f-sub8 #x6d)) + (if prbit + (set (dr fsdn) (c-call DF "sh64_fsqrtd" (dr fsdn))) + (set fsdn (c-call SF "sh64_fsqrts" fsdn)))) + +(dshci fsts "Floating point store status register" + (FP-INSN) + "fsts fpul, $frn" + (+ (f-op4 15) frn (f-sub8 13)) + (set frn fpul)) + +(dshci fsub "Floating point subtract" + (FP-INSN) + "fsub $fsdm, $fsdn" + (+ (f-op4 15) fsdn fsdm (f-sub4 1)) + (if prbit + (set (dr fsdn) (c-call DF "sh64_fsubd" (dr fsdn) (dr fsdm))) + (set fsdn (c-call SF "sh64_fsubs" fsdn fsdm)))) + +(dshci ftrc "Floating point truncate" + (FP-INSN) + "ftrc $fsdn, fpul" + (+ (f-op4 15) fsdn (f-sub8 #x3d)) + (set fpul (if SF prbit + (c-call SF "sh64_ftrcdl" (dr fsdn)) + (c-call SF "sh64_ftrcsl" fsdn)))) + +(dshci ftrv "Floating point transform vector" + (FP-INSN) + "ftrv xmtrx, $fvn" + (+ (f-op4 15) fvn (f-sub10 #x1fd)) + (sequence ((QI n) (SF res)) + (set n (index-of fvn)) + (set res (c-call SF "sh64_fmuls" (reg h-xf 0) (reg h-frc n))) + (set res (c-call SF "sh64_fadds" res (c-call SF "sh64_fmuls" (reg h-xf 4) (reg h-frc (add n 1))))) + (set res (c-call SF "sh64_fadds" res (c-call SF "sh64_fmuls" (reg h-xf 8) (reg h-frc (add n 2))))) + (set res (c-call SF "sh64_fadds" res (c-call SF "sh64_fmuls" (reg h-xf 12) (reg h-frc (add n 3))))) + (set (reg h-frc n) res) + (set res (c-call SF "sh64_fmuls" (reg h-xf 1) (reg h-frc n))) + (set res (c-call SF "sh64_fadds" res (c-call SF "sh64_fmuls" (reg h-xf 5) (reg h-frc (add n 1))))) + (set res (c-call SF "sh64_fadds" res (c-call SF "sh64_fmuls" (reg h-xf 9) (reg h-frc (add n 2))))) + (set res (c-call SF "sh64_fadds" res (c-call SF "sh64_fmuls" (reg h-xf 13) (reg h-frc (add n 3))))) + (set (reg h-frc (add n 1)) res) + (set res (c-call SF "sh64_fmuls" (reg h-xf 2) (reg h-frc n))) + (set res (c-call SF "sh64_fadds" res (c-call SF "sh64_fmuls" (reg h-xf 6) (reg h-frc (add n 1))))) + (set res (c-call SF "sh64_fadds" res (c-call SF "sh64_fmuls" (reg h-xf 10) (reg h-frc (add n 2))))) + (set res (c-call SF "sh64_fadds" res (c-call SF "sh64_fmuls" (reg h-xf 14) (reg h-frc (add n 3))))) + (set (reg h-frc (add n 2)) res) + (set res (c-call SF "sh64_fmuls" (reg h-xf 3) (reg h-frc n))) + (set res (c-call SF "sh64_fadds" res (c-call SF "sh64_fmuls" (reg h-xf 7) (reg h-frc (add n 1))))) + (set res (c-call SF "sh64_fadds" res (c-call SF "sh64_fmuls" (reg h-xf 11) (reg h-frc (add n 2))))) + (set res (c-call SF "sh64_fadds" res (c-call SF "sh64_fmuls" (reg h-xf 15) (reg h-frc (add n 3))))) + (set (reg h-frc (add n 3)) res))) + +(dshci jmp "Jump" + () + "jmp @$rn" + (+ (f-op4 4) rn (f-sub8 43)) + (delay 1 (set pc rn))) + +(dshci jsr "Jump to subroutine" + () + "jsr @$rn" + (+ (f-op4 4) rn (f-sub8 11)) + (delay 1 (sequence () + (set pr (add pc 4)) + (set pc rn)))) + +(dshci ldc "Load control register (GBR)" + () + "ldc $rn, gbr" + (+ (f-op4 4) rn (f-sub8 30)) + (set gbr rn)) + +(dshci ldcl "Load control register (GBR)" + () + "ldc.l @${rn}+, gbr" + (+ (f-op4 4) rn (f-sub8 39)) + (sequence () + (set gbr (mem SI rn)) + (set rn (add rn 4)))) + +(dshci lds-fpscr "Load status register (FPSCR)" + () + "lds $rn, fpscr" + (+ (f-op4 4) rn (f-sub8 106)) + (set fpscr rn)) + +(dshci ldsl-fpscr "Load status register (FPSCR)" + () + "lds.l @${rn}+, fpscr" + (+ (f-op4 4) rn (f-sub8 102)) + (sequence () + (set fpscr (mem SI rn)) + (set rn (add rn 4)))) + +(dshci lds-fpul "Load status register (FPUL)" + () + "lds $rn, fpul" + (+ (f-op4 4) rn (f-sub8 90)) + ; Use subword to convert rn's mode. + (set fpul (subword SF rn 0))) + +(dshci ldsl-fpul "Load status register (FPUL)" + () + "lds.l @${rn}+, fpul" + (+ (f-op4 4) rn (f-sub8 86)) + (sequence () + (set fpul (mem SF rn)) + (set rn (add rn 4)))) + +(dshci lds-mach "Load status register (MACH)" + () + "lds $rn, mach" + (+ (f-op4 4) rn (f-sub8 10)) + (set mach rn)) + +(dshci ldsl-mach "Load status register (MACH), post-increment" + () + "lds.l @${rn}+, mach" + (+ (f-op4 4) rn (f-sub8 6)) + (sequence () + (set mach (mem SI rn)) + (set rn (add rn 4)))) + +(dshci lds-macl "Load status register (MACL)" + () + "lds $rn, macl" + (+ (f-op4 4) rn (f-sub8 26)) + (set macl rn)) + +(dshci ldsl-macl "Load status register (MACL), post-increment" + () + "lds.l @${rn}+, macl" + (+ (f-op4 4) rn (f-sub8 22)) + (sequence () + (set macl (mem SI rn)) + (set rn (add rn 4)))) + +(dshci lds-pr "Load status register (PR)" + () + "lds $rn, pr" + (+ (f-op4 4) rn (f-sub8 42)) + (set pr rn)) + +(dshci ldsl-pr "Load status register (PR), post-increment" + () + "lds.l @${rn}+, pr" + (+ (f-op4 4) rn (f-sub8 38)) + (sequence () + (set pr (mem SI rn)) + (set rn (add rn 4)))) + +(dshci macl "Multiply and accumulate (long)" + () + "mac.l @${rm}+, @${rn}+" + (+ (f-op4 0) rn rm (f-sub4 15)) + (sequence ((DI tmpry) (DI mac) (DI result) (SI x) (SI y)) + (set x (mem SI rn)) + (set rn (add rn 4)) + (if (eq (index-of rn) (index-of rm)) + (sequence () + (set rn (add rn 4)) + (set rm (add rm 4)))) + (set y (mem SI rm)) + (set rm (add rm 4)) + (set tmpry (mul (zext DI x) (zext DI y))) + (set mac (or DI (sll (zext DI mach) 32) (zext DI macl))) + (set result (add mac tmpry)) + (sequence () + (if sbit + (sequence ((SI min) (SI max)) + (set max (srl (inv DI 0) 16)) + ; Preserve bit 48 for sign. + (set min (srl (inv DI 0) 15)) + (if (gt result max) + (set result max) + (if (lt result min) + (set result min))))) + (set mach (subword SI result 0)) + (set macl (subword SI result 1))))) + +(dshci macw "Multiply and accumulate (word)" + () + "mac.w @${rm}+, @${rn}+" + (+ (f-op4 4) rn rm (f-sub4 15)) + (sequence ((SI tmpry) (DI mac) (DI result) (HI x) (HI y)) + (set x (mem HI rn)) + (set rn (add rn 2)) + (if (eq (index-of rn) (index-of rm)) + (sequence () + (set rn (add rn 2)) + (set rm (add rm 2)))) + (set y (mem HI rm)) + (set rm (add rm 2)) + (set tmpry (mul (zext SI x) (zext SI y))) + (if sbit + (sequence () + (if (add-oflag tmpry macl 0) + (set mach 1)) + (set macl (add tmpry macl))) + (sequence () + (set mac (or DI (sll (zext DI mach) 32) (zext DI macl))) + (set result (add mac (ext DI tmpry))) + (set mach (subword SI result 0)) + (set macl (subword SI result 1)))))) + +(dshci mov "Move" + () + "mov $rm64, $rn64" + (+ (f-op4 6) rn64 rm64 (f-sub4 3)) + (set rn64 rm64)) + +(dshci movi "Move immediate" + () + "mov #$imm8, $rn" + (+ (f-op4 14) rn imm8) + (set rn (ext DI (and QI imm8 255)))) + +(dshci movb1 "Store byte to memory (register indirect w/ zero displacement)" + () + "mov.b $rm, @$rn" + (+ (f-op4 2) rn rm (f-sub4 0)) + (set (mem UQI rn) (subword UQI rm 3))) + +(dshci movb2 "Store byte to memory (register indirect w/ pre-decrement)" + () + "mov.b $rm, @-$rn" + (+ (f-op4 2) rn rm (f-sub4 4)) + (sequence ((DI addr)) + (set addr (sub rn 1)) + (set (mem UQI addr) (subword UQI rm 3)) + (set rn addr))) + +(dshci movb3 "Store byte to memory (register/register indirect)" + () + "mov.b $rm, @(r0,$rn)" + (+ (f-op4 0) rn rm (f-sub4 4)) + (set (mem UQI (add r0 rn)) (subword UQI rm 3))) + +(dshci movb4 "Store byte to memory (GBR-relative w/ displacement)" + () + "mov.b r0, @($imm8, gbr)" + (+ (f-op8 #xc0) imm8) + (sequence ((DI addr)) + (set addr (add gbr imm8)) + (set (mem UQI addr) (subword UQI r0 3)))) + +(dshci movb5 "Store byte to memory (register indirect w/ displacement)" + () + "mov.b r0, @($imm4, $rm)" + (+ (f-op8 #x80) rm imm4) + (sequence ((DI addr)) + (set addr (add rm imm4)) + (set (mem UQI addr) (subword UQI r0 3)))) + +(dshci movb6 "Load byte from memory (register indirect w/ zero displacement)" + () + "mov.b @$rm, $rn" + (+ (f-op4 6) rn rm (f-sub4 0)) + (set rn (ext SI (mem QI rm)))) + +(dshci movb7 "Load byte from memory (register indirect w/ post-increment)" + () + "mov.b @${rm}+, $rn" + (+ (f-op4 6) rn rm (f-sub4 4)) + (sequence ((QI data)) + (set data (mem QI rm)) + (if (eq (index-of rm) (index-of rn)) + (set rm (ext SI data)) + (set rm (add rm 1))) + (set rn (ext SI data)))) + +(dshci movb8 "Load byte from memory (register/register indirect)" + () + "mov.b @(r0, $rm), $rn" + (+ (f-op4 0) rn rm (f-sub4 12)) + (set rn (ext SI (mem QI (add r0 rm))))) + +(dshci movb9 "Load byte from memory (GBR-relative with displacement)" + () + "mov.b @($imm8, gbr), r0" + (+ (f-op8 #xc4) imm8) + (set r0 (ext SI (mem QI (add gbr imm8))))) + +(dshci movb10 "Load byte from memory (register indirect w/ displacement)" + () + "mov.b @($imm4, $rm), r0" + (+ (f-op8 #x84) rm imm4) + (set r0 (ext SI (mem QI (add rm imm4))))) + +(dshci movl1 "Store long word to memory (register indirect w/ zero displacement)" + () + "mov.l $rm, @$rn" + (+ (f-op4 2) rn rm (f-sub4 2)) + (set (mem SI rn) rm)) + +(dshci movl2 "Store long word to memory (register indirect w/ pre-decrement)" + () + "mov.l $rm, @-$rn" + (+ (f-op4 2) rn rm (f-sub4 6)) + (sequence ((SI addr)) + (set addr (sub rn 4)) + (set (mem SI addr) rm) + (set rn addr))) + +(dshci movl3 "Store long word to memory (register/register indirect)" + () + "mov.l $rm, @(r0, $rn)" + (+ (f-op4 0) rn rm (f-sub4 6)) + (set (mem SI (add r0 rn)) rm)) + +(dshci movl4 "Store long word to memory (GBR-relative w/ displacement)" + () + "mov.l r0, @($imm8x4, gbr)" + (+ (f-op8 #xc2) imm8x4) + (set (mem SI (add gbr imm8x4)) r0)) + +(dshci movl5 "Store long word to memory (register indirect w/ displacement)" + () + "mov.l $rm, @($imm4x4, $rn)" + (+ (f-op4 1) rn rm imm4x4) + (set (mem SI (add rn imm4x4)) rm)) + +(dshci movl6 "Load long word to memory (register indirect w/ zero displacement)" + () + "mov.l @$rm, $rn" + (+ (f-op4 6) rn rm (f-sub4 2)) + (set rn (mem SI rm))) + +(dshci movl7 "Load long word from memory (register indirect w/ post-increment)" + () + "mov.l @${rm}+, $rn" + (+ (f-op4 6) rn rm (f-sub4 6)) + (sequence () + (set rn (mem SI rm)) + (if (eq (index-of rm) (index-of rn)) + (set rm rn) + (set rm (add rm 4))))) + +(dshci movl8 "Load long word from memory (register/register indirect)" + () + "mov.l @(r0, $rm), $rn" + (+ (f-op4 0) rn rm (f-sub4 14)) + (set rn (mem SI (add r0 rm)))) + +(dshci movl9 "Load long word from memory (GBR-relative w/ displacement)" + () + "mov.l @($imm8x4, gbr), r0" + (+ (f-op8 #xc6) imm8x4) + (set r0 (mem SI (add gbr imm8x4)))) + +(dshci movl10 "Load long word from memory (PC-relative w/ displacement)" + (ILLSLOT) + "mov.l @($imm8x4, pc), $rn" + (+ (f-op4 13) rn imm8x4) + (set rn (mem SI (add imm8x4 (and (add pc 4) (inv 3)))))) + +(dshci movl11 "Load long word from memory (register indirect w/ displacement)" + () + "mov.l @($imm4x4, $rm), $rn" + (+ (f-op4 5) rn rm imm4x4) + (set rn (mem SI (add rm imm4x4)))) + +(dshci movw1 "Store word to memory (register indirect w/ zero displacement)" + () + "mov.w $rm, @$rn" + (+ (f-op4 2) rn rm (f-sub4 1)) + (set (mem HI rn) (subword HI rm 1))) + +(dshci movw2 "Store word to memory (register indirect w/ pre-decrement)" + () + "mov.w $rm, @-$rn" + (+ (f-op4 2) rn rm (f-sub4 5)) + (sequence ((DI addr)) + (set addr (sub rn 2)) + (set (mem HI addr) (subword HI rm 1)) + (set rn addr))) + +(dshci movw3 "Store word to memory (register/register indirect)" + () + "mov.w $rm, @(r0, $rn)" + (+ (f-op4 0) rn rm (f-sub4 5)) + (set (mem HI (add r0 rn)) (subword HI rm 1))) + +(dshci movw4 "Store word to memory (GBR-relative w/ displacement)" + () + "mov.w r0, @($imm8x2, gbr)" + (+ (f-op8 #xc1) imm8x2) + (set (mem HI (add gbr imm8x2)) (subword HI r0 1))) + +(dshci movw5 "Store word to memory (register indirect w/ displacement)" + () + "mov.w r0, @($imm4x2, $rn)" + (+ (f-op8 #x81) rn imm4x2) + (set (mem HI (add rn imm4x2)) (subword HI r0 1))) + +(dshci movw6 "Load word from memory (register indirect w/ zero displacement)" + () + "mov.w @$rm, $rn" + (+ (f-op4 6) rn rm (f-sub4 1)) + (set rn (ext SI (mem HI rm)))) + +(dshci movw7 "Load word from memory (register indirect w/ post-increment)" + () + "mov.w @${rm}+, $rn" + (+ (f-op4 6) rn rm (f-sub4 5)) + (sequence ((HI data)) + (set data (mem HI rm)) + (if (eq (index-of rm) (index-of rn)) + (set rm (ext SI data)) + (set rm (add rm 2))) + (set rn (ext SI data)))) + +(dshci movw8 "Load word from memory (register/register indirect)" + () + "mov.w @(r0, $rm), $rn" + (+ (f-op4 0) rn rm (f-sub4 13)) + (set rn (ext SI (mem HI (add r0 rm))))) + +(dshci movw9 "Load word from memory (GBR-relative w/ displacement)" + () + "mov.w @($imm8x2, gbr), r0" + (+ (f-op8 #xc5) imm8x2) + (set r0 (ext SI (mem HI (add gbr imm8x2))))) + +(dshci movw10 "Load word from memory (PC-relative w/ displacement)" + (ILLSLOT) + "mov.w @($imm8x2, pc), $rn" + (+ (f-op4 9) rn imm8x2) + (set rn (ext SI (mem HI (add (add pc 4) imm8x2))))) + +(dshci movw11 "Load word from memory (register indirect w/ displacement)" + () + "mov.w @($imm4x2, $rm), r0" + (+ (f-op8 #x85) rm imm4x2) + (set r0 (ext SI (mem HI (add rm imm4x2))))) + +(dshci mova "Move effective address" + (ILLSLOT) + "mova @($imm8x4, pc), r0" + (+ (f-op8 #xc7) imm8x4) + (set r0 (add (and (add pc 4) (inv 3)) imm8x4))) + +(dshci movcal "Move with cache block allocation" + () + "movca.l r0, @$rn" + (+ (f-op4 0) rn (f-sub8 #xc3)) + (set (mem SI rn) r0)) + +(dshci movt "Move t-bit" + () + "movt $rn" + (+ (f-op4 0) rn (f-sub8 41)) + (set rn (zext SI tbit))) + +(dshci mull "Multiply" + () + "mul.l $rm, $rn" + (+ (f-op4 0) rn rm (f-sub4 7)) + (set macl (mul rm rn))) + +(dshci mulsw "Multiply words (signed)" + () + "muls.w $rm, $rn" + (+ (f-op4 2) rn rm (f-sub4 15)) + (set macl (mul (ext SI (subword HI rm 1)) (ext SI (subword HI rn 1))))) + +(dshci muluw "Multiply words (unsigned)" + () + "mulu.w $rm, $rn" + (+ (f-op4 2) rn rm (f-sub4 14)) + (set macl (mul (zext SI (subword HI rm 1)) (zext SI (subword HI rn 1))))) + +(dshci neg "Negate" + () + "neg $rm, $rn" + (+ (f-op4 6) rn rm (f-sub4 11)) + (set rn (neg rm))) + +(dshci negc "Negate with carry" + () + "negc $rm, $rn" + (+ (f-op4 6) rn rm (f-sub4 10)) + (sequence ((BI flag)) + (set flag (sub-cflag 0 rm tbit)) + (set rn (subc 0 rm tbit)) + (set tbit flag))) + +(dshci nop "No operation" + () + "nop" + (+ (f-op16 9)) + (nop)) + +(dshci not "Bitwise NOT" + () + "not $rm64, $rn64" + (+ (f-op4 6) rn64 rm64 (f-sub4 7)) + (set rn64 (inv rm64))) + +(dshci ocbi "Invalidate operand cache block" + () + "ocbi @$rn" + (+ (f-op4 0) rn (f-sub8 147)) + (unimp "ocbi")) + +(dshci ocbp "Purge operand cache block" + () + "ocbp @$rn" + (+ (f-op4 0) rn (f-sub8 163)) + (unimp "ocbp")) + +(dshci ocbwb "Write back operand cache block" + () + "ocbwb @$rn" + (+ (f-op4 0) rn (f-sub8 179)) + (unimp "ocbwb")) + +(dshci or "Bitwise OR" + () + "or $rm64, $rn64" + (+ (f-op4 2) rn64 rm64 (f-sub4 11)) + (set rn64 (or rm64 rn64))) + +(dshci ori "Bitwise OR immediate" + () + "or #$uimm8, r0" + (+ (f-op8 #xcb) uimm8) + (set r0 (or r0 (zext DI uimm8)))) + +(dshci orb "Bitwise OR immediate" + () + "or.b #$imm8, @(r0, gbr)" + (+ (f-op8 #xcf) imm8) + (sequence ((DI addr) (UQI data)) + (set addr (add r0 gbr)) + (set data (or (mem UQI addr) imm8)) + (set (mem UQI addr) data))) + +(dshci pref "Prefetch data" + () + "pref @$rn" + (+ (f-op4 0) rn (f-sub8 131)) + (unimp "pref")) + +(dshci rotcl "Rotate with carry left" + () + "rotcl $rn" + (+ (f-op4 4) rn (f-sub8 36)) + (sequence ((BI temp)) + (set temp (srl rn 31)) + (set rn (or (sll rn 1) tbit)) + (set tbit (if BI temp 1 0)))) + +(dshci rotcr "Rotate with carry right" + () + "rotcr $rn" + (+ (f-op4 4) rn (f-sub8 37)) + (sequence ((BI lsbit) (SI temp)) + (set lsbit (if BI (eq (and rn 1) 0) 0 1)) + (set temp tbit) + (set rn (or (srl rn 1) (sll temp 31))) + (set tbit (if BI lsbit 1 0)))) + +(dshci rotl "Rotate left" + () + "rotl $rn" + (+ (f-op4 4) rn (f-sub8 4)) + (sequence ((BI temp)) + (set temp (srl rn 31)) + (set rn (or (sll rn 1) temp)) + (set tbit (if BI temp 1 0)))) + +(dshci rotr "Rotate right" + () + "rotr $rn" + (+ (f-op4 4) rn (f-sub8 5)) + (sequence ((BI lsbit) (SI temp)) + (set lsbit (if BI (eq (and rn 1) 0) 0 1)) + (set temp lsbit) + (set rn (or (srl rn 1) (sll temp 31))) + (set tbit (if BI lsbit 1 0)))) + +(dshci rts "Return from subroutine" + () + "rts" + (+ (f-op16 11)) + (delay 1 (set pc pr))) + +(dshci sets "Set S-bit" + () + "sets" + (+ (f-op16 88)) + (set sbit 1)) + +(dshci sett "Set T-bit" + () + "sett" + (+ (f-op16 24)) + (set tbit 1)) + +(dshci shad "Shift arithmetic dynamic" + () + "shad $rm, $rn" + (+ (f-op4 4) rn rm (f-sub4 12)) + (sequence ((QI shamt)) + (set shamt (and QI rm 31)) + (if (ge rm 0) + (set rn (sll rn shamt)) + (if (ne shamt 0) + (set rn (sra rn (sub 32 shamt))) + (if (lt rn 0) + (set rn (neg 1)) + (set rn 0)))))) + +(dshci shal "Shift left arithmetic one bit" + () + "shal $rn" + (+ (f-op4 4) rn (f-sub8 32)) + (sequence ((BI t)) + (set t (srl rn 31)) + (set rn (sll rn 1)) + (set tbit (if BI t 1 0)))) + +(dshci shar "Shift right arithmetic one bit" + () + "shar $rn" + (+ (f-op4 4) rn (f-sub8 33)) + (sequence ((BI t)) + (set t (and rn 1)) + (set rn (sra rn 1)) + (set tbit (if BI t 1 0)))) + +(dshci shld "Shift logical dynamic" + () + "shld $rm, $rn" + (+ (f-op4 4) rn rm (f-sub4 13)) + (sequence ((QI shamt)) + (set shamt (and QI rm 31)) + (if (ge rm 0) + (set rn (sll rn shamt)) + (if (ne shamt 0) + (set rn (srl rn (sub 32 shamt))) + (set rn 0))))) + +(dshci shll "Shift left logical one bit" + () + "shll $rn" + (+ (f-op4 4) rn (f-sub8 0)) + (sequence ((BI t)) + (set t (srl rn 31)) + (set rn (sll rn 1)) + (set tbit (if BI t 1 0)))) + +(dshci shll2 "Shift left logical two bits" + () + "shll2 $rn" + (+ (f-op4 4) rn (f-sub8 8)) + (set rn (sll rn 2))) + +(dshci shll8 "Shift left logical eight bits" + () + "shll8 $rn" + (+ (f-op4 4) rn (f-sub8 24)) + (set rn (sll rn 8))) + +(dshci shll16 "Shift left logical sixteen bits" + () + "shll16 $rn" + (+ (f-op4 4) rn (f-sub8 40)) + (set rn (sll rn 16))) + +(dshci shlr "Shift right logical one bit" + () + "shlr $rn" + (+ (f-op4 4) rn (f-sub8 1)) + (sequence ((BI t)) + (set t (and rn 1)) + (set rn (srl rn 1)) + (set tbit (if BI t 1 0)))) + +(dshci shlr2 "Shift right logical two bits" + () + "shlr2 $rn" + (+ (f-op4 4) rn (f-sub8 9)) + (set rn (srl rn 2))) + +(dshci shlr8 "Shift right logical eight bits" + () + "shlr8 $rn" + (+ (f-op4 4) rn (f-sub8 25)) + (set rn (srl rn 8))) + +(dshci shlr16 "Shift right logical sixteen bits" + () + "shlr16 $rn" + (+ (f-op4 4) rn (f-sub8 41)) + (set rn (srl rn 16))) + +(dshci stc-gbr "Store control register (GBR)" + () + "stc gbr, $rn" + (+ (f-op4 0) rn (f-sub8 18)) + (set rn gbr)) + +(dshci stcl-gbr "Store control register (GBR)" + () + "stc.l gbr, @-$rn" + (+ (f-op4 4) rn (f-sub8 19)) + (sequence ((DI addr)) + (set addr (sub rn 4)) + (set (mem SI addr) gbr) + (set rn addr))) + +(dshci sts-fpscr "Store status register (FPSCR)" + () + "sts fpscr, $rn" + (+ (f-op4 0) rn (f-sub8 106)) + (set rn fpscr)) + +(dshci stsl-fpscr "Store status register (FPSCR)" + () + "sts.l fpscr, @-$rn" + (+ (f-op4 4) rn (f-sub8 98)) + (sequence ((DI addr)) + (set addr (sub rn 4)) + (set (mem SI addr) fpscr) + (set rn addr))) + +(dshci sts-fpul "Store status register (FPUL)" + () + "sts fpul, $rn" + (+ (f-op4 0) rn (f-sub8 90)) + (set rn (subword SI fpul 0))) + +(dshci stsl-fpul "Store status register (FPUL)" + () + "sts.l fpul, @-$rn" + (+ (f-op4 4) rn (f-sub8 82)) + (sequence ((DI addr)) + (set addr (sub rn 4)) + (set (mem SF addr) fpul) + (set rn addr))) + +(dshci sts-mach "Store status register (MACH)" + () + "sts mach, $rn" + (+ (f-op4 0) rn (f-sub8 10)) + (set rn mach)) + +(dshci stsl-mach "Store status register (MACH)" + () + "sts.l mach, @-$rn" + (+ (f-op4 4) rn (f-sub8 2)) + (sequence ((DI addr)) + (set addr (sub rn 4)) + (set (mem SI addr) mach) + (set rn addr))) + +(dshci sts-macl "Store status register (MACL)" + () + "sts macl, $rn" + (+ (f-op4 0) rn (f-sub8 26)) + (set rn macl)) + +(dshci stsl-macl "Store status register (MACL)" + () + "sts.l macl, @-$rn" + (+ (f-op4 4) rn (f-sub8 18)) + (sequence ((DI addr)) + (set addr (sub rn 4)) + (set (mem SI addr) macl) + (set rn addr))) + +(dshci sts-pr "Store status register (PR)" + () + "sts pr, $rn" + (+ (f-op4 0) rn (f-sub8 42)) + (set rn pr)) + +(dshci stsl-pr "Store status register (PR)" + () + "sts.l pr, @-$rn" + (+ (f-op4 4) rn (f-sub8 34)) + (sequence ((DI addr)) + (set addr (sub rn 4)) + (set (mem SI addr) pr) + (set rn addr))) + +(dshci sub "Subtract" + () + "sub $rm, $rn" + (+ (f-op4 3) rn rm (f-sub4 8)) + (set rn (sub rn rm))) + +(dshci subc "Subtract and detect carry" + () + "subc $rm, $rn" + (+ (f-op4 3) rn rm (f-sub4 10)) + (sequence ((BI flag)) + (set flag (sub-cflag rn rm tbit)) + (set rn (subc rn rm tbit)) + (set tbit flag))) + +(dshci subv "Subtract and detect overflow" + () + "subv $rm, $rn" + (+ (f-op4 3) rn rm (f-sub4 11)) + (sequence ((BI t)) + (set t (sub-oflag rn rm 0)) + (set rn (sub rn rm)) + (set tbit (if BI t 1 0)))) + +(dshci swapb "Swap bytes" + () + "swap.b $rm, $rn" + (+ (f-op4 6) rn rm (f-sub4 8)) + (sequence ((UHI top-half) (UQI byte1) (UQI byte0)) + (set top-half (subword HI rm 0)) + (set byte1 (subword QI rm 2)) + (set byte0 (subword QI rm 3)) + (set rn (or SI (sll SI top-half 16) (or SI (sll SI byte0 8) byte1))))) + +(dshci swapw "Swap words" + () + "swap.w $rm, $rn" + (+ (f-op4 6) rn rm (f-sub4 9)) + (set rn (or (srl rm 16) (sll rm 16)))) + +(dshci tasb "Test and set byte" + () + "tas.b @$rn" + (+ (f-op4 4) rn (f-sub8 27)) + (sequence ((UQI byte)) + (set byte (mem UQI rn)) + (set tbit (if BI (eq byte 0) 1 0)) + (set byte (or byte 128)) + (set (mem UQI rn) byte))) + +(dshci trapa "Trap" + (ILLSLOT) + "trapa #$uimm8" + (+ (f-op8 #xc3) uimm8) + (c-call "sh64_compact_trapa" uimm8 pc)) + +(dshci tst "Test and set t-bit" + () + "tst $rm, $rn" + (+ (f-op4 2) rn rm (f-sub4 8)) + (set tbit (if BI (eq (and rm rn) 0) 1 0))) + +(dshci tsti "Test and set t-bit immediate" + () + "tst #$uimm8, r0" + (+ (f-op8 #xc8) uimm8) + (set tbit (if BI (eq (and r0 (zext SI uimm8)) 0) 1 0))) + +(dshci tstb "Test and set t-bit immedate with memory byte" + () + "tst.b #$imm8, @(r0, gbr)" + (+ (f-op8 #xcc) imm8) + (sequence ((DI addr)) + (set addr (add r0 gbr)) + (set tbit (if BI (eq (and (mem UQI addr) imm8) 0) 1 0)))) + +(dshci xor "Exclusive OR" + () + "xor $rm64, $rn64" + (+ (f-op4 2) rn64 rm64 (f-sub4 10)) + (set rn64 (xor rn64 rm64))) + +(dshci xori "Exclusive OR immediate" + () + "xor #$uimm8, r0" + (+ (f-op8 #xca) uimm8) + (set (reg h-gr 0) (xor (reg h-gr 0) (zext DI uimm8)))) + +(dshci xorb "Exclusive OR immediate with memory byte" + () + "xor.b #$imm8, @(r0, gbr)" + (+ (f-op8 #xce) imm8) + (sequence ((DI addr) (UQI data)) + (set addr (add r0 gbr)) + (set data (xor (mem UQI addr) imm8)) + (set (mem UQI addr) data))) + +(dshci xtrct "Extract" + () + "xtrct $rm, $rn" + (+ (f-op4 2) rn rm (f-sub4 13)) + (set rn (or (sll rm 16) (srl rn 16)))) diff --git a/cpu/sh64-media.cpu b/cpu/sh64-media.cpu new file mode 100644 index 00000000000..80dd74a89fb --- /dev/null +++ b/cpu/sh64-media.cpu @@ -0,0 +1,1733 @@ +; Hitachi SHmedia instruction set description. -*- Scheme -*- +; +; Copyright 2000, 2001, 2007, 2009 Free Software Foundation, Inc. +; +; Contributed by Red Hat Inc; developed under contract from Hitachi +; Semiconductor (America) Inc. +; +; 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. + + +; dshmf -- define-normal-sh-media-field + +(define-pmacro (dshmf xname xcomment ignored xstart xlength) + (dnf xname xcomment ((ISA media)) xstart xlength)) + +; dshmop -- define-normal-sh-media-operand + +(define-pmacro (dshmop xname xcomment ignored xhardware xfield) + (dnop xname xcomment ((ISA media)) xhardware xfield)) + +; dnshmi -- define-normal-sh-media-insn + +(define-pmacro (dshmi xname xcomment xattrs xsyntax xformat xsemantics) + (define-insn + (name xname) + (comment xcomment) + (.splice attrs (.unsplice xattrs) (ISA media)) + (syntax xsyntax) + (format xformat) + (semantics xsemantics))) + +; Saturation functions. +; Force a value `i' into words `n' bits wide. +; See Hitachi SH-5 CPU core, volume 2, p. 25 for details. + +; saturate -- signed saturatation function + +(define-pmacro (saturate mode n i) + (if mode (lt i (neg mode (sll mode 1 (sub n 1)))) + (neg (sll mode 1 (sub n 1))) + (if mode (lt i (sll mode 1 (sub n 1))) + i + (sub mode (sll mode 1 (sub n 1)) 1)))) + +; usaturate -- unsigned saturation function + +(define-pmacro (usaturate mode n i) + (if mode (lt i (const mode 0)) + (const mode 0) + (if mode (lt i (sll mode 1 n)) + i + (sub mode (sll mode 1 n) 1)))) + + +; Ifields. + +(dshmf f-op "Opcode" () 31 6) +(dshmf f-ext "Extension opcode" () 19 4) +(dshmf f-rsvd "Reserved" (RESERVED) 3 4) + +(dshmf f-left "Left register" () 25 6) +(dshmf f-right "Right register" () 15 6) +(dshmf f-dest "Destination register" () 9 6) + +(define-multi-ifield + (name f-left-right) + (comment "Left and right matched register pair") + (attrs (ISA media)) + (mode UINT) + (subfields f-left f-right) + (insert (sequence () + (set (ifield f-left) + (and (ifield f-left-right) 63)) + (set (ifield f-right) + (and (ifield f-left-right) 63)))) + (extract (set (ifield f-left-right) (ifield f-left))) +) + +(dshmf f-tra "Target register" () 6 3) +(dshmf f-trb "Target register" () 22 3) +(dshmf f-likely "Likely bit" () 9 1) +(dshmf f-25 "Three unused bits at bit 25" () 25 3) +(dshmf f-8-2 "Two unused bits at bit 8" () 8 2) + +(df f-imm6 "Immediate value (6 bits)" ((ISA media)) 15 6 INT #f #f) +(df f-imm10 "Immediate value (10 bits)" ((ISA media)) 19 10 INT #f #f) +(df f-imm16 "Immediate value (16 bits)" ((ISA media)) 25 16 INT #f #f) + +(dshmf f-uimm6 "Immediate value (6 bits)" () 15 6) +(dshmf f-uimm16 "Immediate value (16 bits)" () 25 16) + +; Various displacement fields. +; The 10 bit field, for example, has different scaling for displacements. + +(df f-disp6 "Displacement (6 bits)" ((ISA media)) 15 6 INT #f #f) + +(df f-disp6x32 "Displacement (6 bits)" ((ISA media)) 15 6 INT + ((value pc) (sra SI value 5)) + ((value pc) (sll SI value 5))) + +(df f-disp10 "Displacement (10 bits)" ((ISA media)) 19 10 INT #f #f) + +(df f-disp10x8 "Displacement (10 bits)" ((ISA media)) 19 10 INT + ((value pc) (sra SI value 3)) + ((value pc) (sll SI value 3))) + +(df f-disp10x4 "Displacement (10 bits)" ((ISA media)) 19 10 INT + ((value pc) (sra SI value 2)) + ((value pc) (sll SI value 2))) + +(df f-disp10x2 "Displacement (10 bits)" ((ISA media)) 19 10 INT + ((value pc) (sra SI value 1)) + ((value pc) (sll SI value 1))) + +(df f-disp16 "Displacement (16 bits)" ((ISA media) PCREL-ADDR) 25 16 INT + ((value pc) (sra DI value 2)) + ((value pc) (add DI (sll DI value 2) pc))) + + +; Operands. + +(dshmop rm "Left general purpose reg" () h-gr f-left) +(dshmop rn "Right general purpose reg" () h-gr f-right) +(dshmop rd "Destination general purpose reg" () h-gr f-dest) + +(dshmop frg "Left single precision register" () h-fr f-left) +(dshmop frh "Right single precision register" () h-fr f-right) +(dshmop frf "Destination single precision reg" () h-fr f-dest) +(dshmop frgh "Single precision register pair" () h-fr f-left-right) + +(dshmop fpf "Pair of single precision registers" () h-fp f-dest) + +(dshmop fvg "Left single precision vector" () h-fv f-left) +(dshmop fvh "Right single precision vector" () h-fv f-right) +(dshmop fvf "Destination single precision vector" () h-fv f-dest) +(dshmop mtrxg "Left single precision matrix" () h-fmtx f-left) + +(dshmop drg "Left double precision register" () h-dr f-left) +(dshmop drh "Right double precision register" () h-dr f-right) +(dshmop drf "Destination double precision reg" () h-dr f-dest) +(dshmop drgh "Double precision register pair" () h-dr f-left-right) + +(dshmop fpscr "Floating point status register" () h-fpscr f-nil) +(dshmop crj "Control register j" () h-cr f-dest) +(dshmop crk "Control register k" () h-cr f-left) + +(dshmop tra "Target register a" () h-tr f-tra) +(dshmop trb "Target register b" () h-tr f-trb) + +(dshmop disp6 "Displacement (6 bits)" () h-sint f-disp6) +(dshmop disp6x32 "Displacement (6 bits, scale 32)" () h-sint f-disp6x32) +(dshmop disp10 "Displacement (10 bits)" () h-sint f-disp10) +(dshmop disp10x2 "Displacement (10 bits, scale 2)" () h-sint f-disp10x2) +(dshmop disp10x4 "Displacement (10 bits, scale 4)" () h-sint f-disp10x4) +(dshmop disp10x8 "Displacement (10 bits, scale 8)" () h-sint f-disp10x8) +(dshmop disp16 "Displacement (16 bits)" () h-sint f-disp16) + +(dshmop imm6 "Immediate (6 bits)" () h-sint f-imm6) +(dshmop imm10 "Immediate (10 bits)" () h-sint f-imm10) +(dshmop imm16 "Immediate (16 bits)" () h-sint f-imm16) +(dshmop uimm6 "Immediate (6 bits)" () h-uint f-uimm6) +(dshmop uimm16 "Unsigned immediate (16 bits)" () h-uint f-uimm16) + +; FIXME: provide these parse/print functions in `sh-media.opc'. + +(define-operand (name likely) (comment "Likely branch?") (attrs (ISA media)) + (type h-uint) (index f-likely) (handlers (parse "likely") (print "likely"))) + + +; Instructions. + +(dshmi add "Add" + () + "add $rm, $rn, $rd" + (+ (f-op 0) rm (f-ext 9) rn rd (f-rsvd 0)) + (set rd (add rm rn))) + +(dshmi addl "Add long" + () + "add.l $rm, $rn, $rd" + (+ (f-op 0) rm (f-ext 8) rn rd (f-rsvd 0)) + (set rd (add (subword SI rm 1) (subword SI rn 1)))) + +(dshmi addi "Add immediate" + () + "addi $rm, $disp10, $rd" + (+ (f-op 52) rm disp10 rd (f-rsvd 0)) + (set rd (add rm (ext DI disp10)))) + +(dshmi addil "Add immediate long" + () + "addi.l $rm, $disp10, $rd" + (+ (f-op 53) rm disp10 rd (f-rsvd 0)) + (set rd (ext DI (add (ext SI disp10) (subword SI rm 1))))) + +(dshmi addzl "Add zero extended long" + () + "addz.l $rm, $rn, $rd" + (+ (f-op 0) rm (f-ext 12) rn rd (f-rsvd 0)) + (set rd (zext DI (add (subword SI rm 1) (subword SI rn 1))))) + +(dshmi alloco "Allocate operand cache block" + () + "alloco $rm, $disp6x32" + (+ (f-op 56) rm (f-ext 4) disp6x32 (f-dest 63) (f-rsvd 0)) + (unimp "alloco")) + +(dshmi and "AND" + () + "and $rm, $rn, $rd" + (+ (f-op 1) rm (f-ext 11) rn rd (f-rsvd 0)) + (set rd (and rm rn))) + +(dshmi andc "AND complement" + () + "andc $rm, $rn, $rd" + (+ (f-op 1) rm (f-ext 15) rn rd (f-rsvd 0)) + (set rd (and rm (inv rn)))) + +(dshmi andi "AND immediate" + () + "andi $rm, $disp10, $rd" + (+ (f-op 54) rm disp10 rd (f-rsvd 0)) + (set rd (and rm (ext DI disp10)))) + +(dshmi beq "Branch if equal" + () + "beq$likely $rm, $rn, $tra" + (+ (f-op 25) rm (f-ext 1) rn likely (f-8-2 0) tra (f-rsvd 0)) + (if (eq rm rn) + (set pc tra))) + +(dshmi beqi "Branch if equal immediate" + () + "beqi$likely $rm, $imm6, $tra" + (+ (f-op 57) rm (f-ext 1) imm6 likely (f-8-2 0) tra (f-rsvd 0)) + (if (eq rm (ext DI imm6)) + (set pc tra))) + +(dshmi bge "Branch if greater than or equal" + () + "bge$likely $rm, $rn, $tra" + (+ (f-op 25) rm (f-ext 3) rn likely (f-8-2 0) tra (f-rsvd 0)) + (if (ge rm rn) + (set pc tra))) + +(dshmi bgeu "Branch if greater than or equal (unsigned comparison)" + () + "bgeu$likely $rm, $rn, $tra" + (+ (f-op 25) rm (f-ext 11) rn likely (f-8-2 0) tra (f-rsvd 0)) + (if (geu rm rn) + (set pc tra))) + +(dshmi bgt "Branch greater than" + () + "bgt$likely $rm, $rn, $tra" + (+ (f-op 25) rm (f-ext 7) rn likely (f-8-2 0) tra (f-rsvd 0)) + (if (gt rm rn) + (set pc tra))) + +(dshmi bgtu "Branch greater than (unsigned comparison)" + () + "bgtu$likely $rm, $rn, $tra" + (+ (f-op 25) rm (f-ext 15) rn likely (f-8-2 0) tra (f-rsvd 0)) + (if (gtu rm rn) + (set pc tra))) + +(dshmi blink "Branch and link" + () + "blink $trb, $rd" + (+ (f-op 17) (f-25 0) trb (f-ext 1) (f-right 63) rd (f-rsvd 0)) + (sequence () + (set rd (or (add pc 4) 1)) + (set pc trb))) + +(dshmi bne "Branch if not equal" + () + "bne$likely $rm, $rn, $tra" + (+ (f-op 25) rm (f-ext 5) rn likely (f-8-2 0) tra (f-rsvd 0)) + (if (ne rm rn) + (set pc tra))) + +(dshmi bnei "Branch if not equal immediate" + () + "bnei$likely $rm, $imm6, $tra" + (+ (f-op 57) rm (f-ext 5) rn likely (f-8-2 0) tra (f-rsvd 0)) + (if (ne rm (ext DI imm6)) + (set pc tra))) + +(dshmi brk "Breakpoint instruction" + () + "brk" + (+ (f-op 27) (f-left 63) (f-ext 5) (f-right 63) (f-dest 63) (f-rsvd 0)) + (c-call "sh64_break" pc)) + +(define-pmacro (-byterev-step) + (sequence () + (set result (or (sll result 8) (and source 255))) + (set source (srl source 8))) +) + +(dshmi byterev "Byte reverse" + () + "byterev $rm, $rd" + (+ (f-op 0) rm (f-ext 15) (f-right 63) rd (f-rsvd 0)) + (sequence ((DI source) (DI result)) + (set source rm) + (set result 0) + (-byterev-step) + (-byterev-step) + (-byterev-step) + (-byterev-step) + (-byterev-step) + (-byterev-step) + (-byterev-step) + (-byterev-step) + (set rd result))) + +(dshmi cmpeq "Compare equal" + () + "cmpeq $rm, $rn, $rd" + (+ (f-op 0) rm (f-ext 1) rn rd (f-rsvd 0)) + (set rd (if DI (eq rm rn) 1 0))) + +(dshmi cmpgt "Compare greater than" + () + "cmpgt $rm, $rn, $rd" + (+ (f-op 0) rm (f-ext 3) rn rd (f-rsvd 0)) + (set rd (if DI (gt rm rn) 1 0))) + +(dshmi cmpgtu "Compare greater than (unsigned comparison)" + () + "cmpgtu $rm,$rn, $rd" + (+ (f-op 0) rm (f-ext 7) rn rd (f-rsvd 0)) + (set rd (if DI (gtu rm rn) 1 0))) + +(dshmi cmveq "Conditional move if equal to zero" + () + "cmveq $rm, $rn, $rd" + (+ (f-op 8) rm (f-ext 1) rn rd (f-rsvd 0)) + (if (eq rm 0) + (set rd rn))) + +(dshmi cmvne "Conditional move if not equal to zero" + () + "cmvne $rm, $rn, $rd" + (+ (f-op 8) rm (f-ext 5) rn rd (f-rsvd 0)) + (if (ne rm 0) + (set rd rn))) + +(dshmi fabsd "Floating point absolute (double)" + () + "fabs.d $drgh, $drf" + (+ (f-op 6) drgh (f-ext 1) drf (f-rsvd 0)) + (set drf (c-call DF "sh64_fabsd" drgh))) + +(dshmi fabss "Floating point absolute (single)" + () + "fabs.s $frgh, $frf" + (+ (f-op 6) frgh (f-ext 0) frf (f-rsvd 0)) + (set frf (c-call SF "sh64_fabss" frgh))) + +(dshmi faddd "Floating point add (double)" + () + "fadd.d $drg, $drh, $drf" + (+ (f-op 13) drg (f-ext 1) drh drf (f-rsvd 0)) + (set drf (c-call DF "sh64_faddd" drg drh))) + +(dshmi fadds "Floating point add (single)" + () + "fadd.s $frg, $frh, $frf" + (+ (f-op 13) frg (f-ext 0) frh frf (f-rsvd 0)) + (set frf (c-call SF "sh64_fadds" frg frh))) + +(dshmi fcmpeqd "Floating point compare if equal (double)" + () + "fcmpeq.d $drg, $drh, $rd" + (+ (f-op 12) drg (f-ext 9) drh rd (f-rsvd 0)) + (set rd (zext DI (c-call BI "sh64_fcmpeqd" drg drh)))) + +(dshmi fcmpeqs "Floating point compare if equal (single)" + () + "fcmpeq.s $frg, $frh, $rd" + (+ (f-op 12) frg (f-ext 8) frh rd (f-rsvd 0)) + (set rd (zext DI (c-call BI "sh64_fcmpeqs" frg frh)))) + +(dshmi fcmpged "Floating compare compare if greater than or equal (double)" + () + "fcmpge.d $drg, $drh, $rd" + (+ (f-op 12) drg (f-ext 15) drh rd (f-rsvd 0)) + (set rd (zext DI (c-call BI "sh64_fcmpged" drg drh)))) + +(dshmi fcmpges "Floating point compare if greater than or equal (single)" + () + "fcmpge.s $frg, $frh, $rd" + (+ (f-op 12) frg (f-ext 14) frh rd (f-rsvd 0)) + (set rd (zext DI (c-call BI "sh64_fcmpges" frg frh)))) + +(dshmi fcmpgtd "Floating point compare if greater than (double)" + () + "fcmpgt.d $drg, $drh, $rd" + (+ (f-op 12) drg (f-ext 13) drh rd (f-rsvd 0)) + (set rd (zext DI (c-call BI "sh64_fcmpgtd" drg drh)))) + +(dshmi fcmpgts "Floating point compare if greater than (single)" + () + "fcmpgt.s $frg, $frh, $rd" + (+ (f-op 12) frg (f-ext 12) frh rd (f-rsvd 0)) + (set rd (zext DI (c-call BI "sh64_fcmpgts" frg frh)))) + +(dshmi fcmpund "Floating point unordered comparison (double)" + () + "fcmpun.d $drg, $drh, $rd" + (+ (f-op 12) drg (f-ext 11) drh rd (f-rsvd 0)) + (set rd (zext DI (c-call BI "sh64_fcmpund" drg drh)))) + +(dshmi fcmpuns "Floating point unordered comparison (single)" + () + "fcmpun.s $frg, $frh, $rd" + (+ (f-op 12) frg (f-ext 10) frh rd (f-rsvd 0)) + (set rd (zext DI (c-call BI "sh64_fcmpuns" frg frh)))) + +(dshmi fcnvds "Floating point coversion (double to single)" + () + "fcnv.ds $drgh, $frf" + (+ (f-op 14) drgh (f-ext 7) frf (f-rsvd 0)) + (set frf (c-call SF "sh64_fcnvds" drgh))) + +(dshmi fcnvsd "Floating point conversion (single to double)" + () + "fcnv.sd $frgh, $drf" + (+ (f-op 14) frgh (f-ext 6) drf (f-rsvd 0)) + (set drf (c-call DF "sh64_fcnvsd" frgh))) + +(dshmi fdivd "Floating point divide (double)" + () + "fdiv.d $drg, $drh, $drf" + (+ (f-op 13) drg (f-ext 5) drh drf (f-rsvd 0)) + (set drf (c-call DF "sh64_fdivd" drg drh))) + +(dshmi fdivs "Floating point divide (single)" + () + "fdiv.s $frg, $frh, $frf" + (+ (f-op 13) frg (f-ext 4) frh frf (f-rsvd 0)) + (set frf (c-call SF "sh64_fdivs" frg frh))) + +(dshmi fgetscr "Floating point get from FPSCR" + () + "fgetscr $frf" + (+ (f-op 7) (f-left 63) (f-ext 2) (f-right 63) frf (f-rsvd 0)) + (unimp "fputscr")) + ; FIXME: this should work! + ; (set frf fpscr)) + +(dshmi fiprs "Floating point inner product (single)" + () + "fipr.s $fvg, $fvh, $frf" + (+ (f-op 5) fvg (f-ext 6) fvh frf (f-rsvd 0)) + (sequence ((UQI g) (UQI h) (SF temp)) + (set g (index-of fvg)) + (set h (index-of fvh)) + (set temp (c-call SF "sh64_fmuls" (reg h-fr g) (reg h-fr h))) + (set temp (c-call SF "sh64_fadds" temp + (c-call SF "sh64_fmuls" (reg h-fr (add g 1)) (reg h-fr (add h 1))))) + (set temp (c-call SF "sh64_fadds" temp + (c-call SF "sh64_fmuls" (reg h-fr (add g 2)) (reg h-fr (add h 2))))) + (set temp (c-call SF "sh64_fadds" temp + (c-call SF "sh64_fmuls" (reg h-fr (add g 3)) (reg h-fr (add h 3))))) + (set frf temp))) + +(dshmi fldd "Floating point load (double)" + () + "fld.d $rm, $disp10x8, $drf" + (+ (f-op 39) rm disp10x8 drf (f-rsvd 0)) + (set drf (mem DF (add rm disp10x8)))) + +(dshmi fldp "Floating point load (pair of singles)" + () + "fld.p $rm, $disp10x8, $fpf" + (+ (f-op 38) rm disp10x8 fpf (f-rsvd 0)) + (sequence ((QI f)) + (set f (index-of fpf)) + (set (reg h-fr f) (mem SF (add rm disp10x8))) + (set (reg h-fr (add f 1)) (mem SF (add rm (add disp10x8 4)))))) + +(dshmi flds "Floating point load (single)" + () + "fld.s $rm, $disp10x4, $frf" + (+ (f-op 37) rm disp10x4 frf (f-rsvd 0)) + (set frf (mem SF (add rm disp10x4)))) + +(dshmi fldxd "Floating point extended load (double)" + () + "fldx.d $rm, $rn, $drf" + (+ (f-op 7) rm (f-ext 9) rn frf (f-rsvd 0)) + (set drf (mem DF (add rm rn)))) + +(dshmi fldxp "Floating point extended load (pair of singles)" + () + "fldx.p $rm, $rn, $fpf" + (+ (f-op 7) rm (f-ext 13) rn fpf (f-rsvd 0)) + (sequence ((QI f)) + (set f (index-of fpf)) + (set (reg h-fr f) (mem SF (add rm rn))) + (set (reg h-fr (add f 1)) (mem SF (add rm (add rn 4)))))) + +(dshmi fldxs "Floating point extended load (single)" + () + "fldx.s $rm, $rn, $frf" + (+ (f-op 7) rm (f-ext 8) rn frf (f-rsvd 0)) + (set frf (mem SF (add rm rn)))) + +(dshmi floatld "Floating point conversion (long to double)" + () + "float.ld $frgh, $drf" + (+ (f-op 14) frgh (f-ext 14) drf (f-rsvd 0)) + (set drf (c-call DF "sh64_floatld" frgh))) + +(dshmi floatls "Floating point conversion (long to single)" + () + "float.ls $frgh, $frf" + (+ (f-op 14) frgh (f-ext 12) frf (f-rsvd 0)) + (set frf (c-call SF "sh64_floatls" frgh))) + +(dshmi floatqd "Floating point conversion (quad to double)" + () + "float.qd $drgh, $drf" + (+ (f-op 14) drgh (f-ext 13) drf (f-rsvd 0)) + (set drf (c-call DF "sh64_floatqd" drgh))) + +(dshmi floatqs "Floating point conversion (quad to single)" + () + "float.qs $drgh, $frf" + (+ (f-op 14) drgh (f-ext 15) frf (f-rsvd 0)) + (set frf (c-call SF "sh64_floatqs" drgh))) + +(dshmi fmacs "Floating point multiply and accumulate (single)" + () + "fmac.s $frg, $frh, $frf" + (+ (f-op 13) frg (f-ext 14) frh frf (f-rsvd 0)) + (set frf (c-call SF "sh64_fadds" frf (c-call SF "sh64_fmuls" frg frh)))) + +(dshmi fmovd "Floating point move double" + () + "fmov.d $drgh, $drf" + (+ (f-op 14) drgh (f-ext 1) drf (f-rsvd 0)) + (set drf drgh)) + +(dshmi fmovdq "Floating point move (double to quad integer)" + () + "fmov.dq $drgh, $rd" + (+ (f-op 12) drgh (f-ext 1) rd (f-rsvd 0)) + (set rd (subword DI drgh 0))) + +(dshmi fmovls "Floating point move (lower to single)" + () + "fmov.ls $rm, $frf" + (+ (f-op 7) rm (f-ext 0) (f-right 63) frf (f-rsvd 0)) + (set frf (subword SF (subword SI rm 1) 0))) + +(dshmi fmovqd "Floating point move (quad to double)" + () + "fmov.qd $rm, $drf" + (+ (f-op 7) rm (f-ext 1) (f-right 63) frf (f-rsvd 0)) + (set drf (subword DF rm 0))) + +(dshmi fmovs "Floating point move (single)" + () + "fmov.s $frgh, $frf" + (+ (f-op 14) frgh (f-ext 0) frf (f-rsvd 0)) + (set frf frgh)) + +(dshmi fmovsl "Floating point move (single to lower)" + () + "fmov.sl $frgh, $rd" + (+ (f-op 12) frgh (f-ext 0) rd (f-rsvd 0)) + (set rd (ext DI (subword SI frgh 1)))) + +(dshmi fmuld "Floating point multiply (double)" + () + "fmul.d $drg, $drh, $drf" + (+ (f-op 13) drg (f-ext 7) drh drf (f-rsvd 0)) + (set drf (c-call DF "sh64_fmuld" drg drh))) + +(dshmi fmuls "Floating point multiply (single)" + () + "fmul.s $frg, $frh, $frf" + (+ (f-op 13) frg (f-ext 6) frh frf (f-rsvd 0)) + (set frf (c-call SF "sh64_fmuls" frg frh))) + +(dshmi fnegd "Floating point negate (double)" + () + "fneg.d $drgh, $drf" + (+ (f-op 6) drgh (f-ext 3) drf (f-rsvd 0)) + (set drf (c-call DF "sh64_fnegd" drgh))) + +(dshmi fnegs "Floating point negate (single)" + () + "fneg.s $frgh, $frf" + (+ (f-op 6) frgh (f-ext 2) frf (f-rsvd 0)) + (set frf (c-call SF "sh64_fnegs" frgh))) + +(dshmi fputscr "Floating point put to FPSCR" + () + "fputscr $frgh" + (+ (f-op 12) frgh (f-ext 2) (f-dest 63) (f-rsvd 0)) + (unimp "fputscr")) + ; FIXME: this should work! + ; (set fpscr (subword SI frgh 0))) + +(dshmi fsqrtd "Floating point square root (double)" + () + "fsqrt.d $drgh, $drf" + (+ (f-op 14) drgh (f-ext 5) drf (f-rsvd 0)) + (set drf (c-call DF "sh64_fsqrtd" drgh))) + +(dshmi fsqrts "Floating point squart root (single)" + () + "fsqrt.s $frgh, $frf" + (+ (f-op 14) frgh (f-ext 4) frf (f-rsvd 0)) + (set frf (c-call SF "sh64_fsqrts" frgh))) + +(dshmi fstd "Floating point store (double)" + () + "fst.d $rm, $disp10x8, $drf" + (+ (f-op 47) rm disp10x8 drf (f-rsvd 0)) + (set (mem DF (add rm disp10x8)) drf)) + +(dshmi fstp "Floating point store (pair of singles)" + () + "fst.p $rm, $disp10x8, $fpf" + (+ (f-op 46) rm disp10x8 fpf (f-rsvd 0)) + (sequence ((QI f)) + (set f (index-of fpf)) + (set (mem SF (add rm disp10x8)) (reg h-fr f)) + (set (mem SF (add rm (add disp10x8 4))) (reg h-fr (add f 1))))) + +(dshmi fsts "Floating point store (single)" + () + "fst.s $rm, $disp10x4, $frf" + (+ (f-op 45) rm disp10x4 frf (f-rsvd 0)) + (set (mem SF (add rm disp10x4)) frf)) + +(dshmi fstxd "Floating point extended store (double)" + () + "fstx.d $rm, $rn, $drf" + (+ (f-op 15) rm (f-ext 9) rn drf (f-rsvd 0)) + (set (mem DF (add rm rn)) drf)) + +(dshmi fstxp "Floating point extended store (pair of singles)" + () + "fstx.p $rm, $rn, $fpf" + (+ (f-op 15) rm (f-ext 13) rn fpf (f-rsvd 0)) + (sequence ((QI f)) + (set f (index-of fpf)) + (set (mem SF (add rm rn)) (reg h-fr f)) + (set (mem SF (add rm (add rn 4))) (reg h-fr (add f 1))))) + +(dshmi fstxs "Floating point extended store (single)" + () + "fstx.s $rm, $rn, $frf" + (+ (f-op 15) rm (f-ext 8) rn frf (f-rsvd 0)) + (set (mem SF (add rm rn)) frf)) + +(dshmi fsubd "Floating point subtract (double)" + () + "fsub.d $drg, $drh, $drf" + (+ (f-op 13) frg (f-ext 3) frh frf (f-rsvd 0)) + (set drf (c-call DF "sh64_fsubd" drg drh))) + +(dshmi fsubs "Floating point subtract (single)" + () + "fsub.s $frg, $frh, $frf" + (+ (f-op 13) frg (f-ext 2) frh frf (f-rsvd 0)) + (set frf (c-call SF "sh64_fsubs" frg frh))) + +(dshmi ftrcdl "Floating point conversion (double to long)" + () + "ftrc.dl $drgh, $frf" + (+ (f-op 14) drgh (f-ext 11) frf (f-rsvd 0)) + (set frf (c-call SF "sh64_ftrcdl" drgh))) + +(dshmi ftrcsl "Floating point conversion (single to long)" + () + "ftrc.sl $frgh, $frf" + (+ (f-op 14) frgh (f-ext 8) frf (f-rsvd 0)) + (set frf (c-call SF "sh64_ftrcsl" frgh))) + +(dshmi ftrcdq "Floating point conversion (double to quad)" + () + "ftrc.dq $drgh, $drf" + (+ (f-op 14) drgh (f-ext 9) frf (f-rsvd 0)) + (set drf (c-call DF "sh64_ftrcdq" drgh))) + +(dshmi ftrcsq "Floating point conversion (single to quad)" + () + "ftrc.sq $frgh, $drf" + (+ (f-op 14) frgh (f-ext 10) drf (f-rsvd 0)) + (set drf (c-call DF "sh64_ftrcsq" frgh))) + +(dshmi ftrvs "Floating point matrix multiply" + () + "ftrv.s $mtrxg, $fvh, $fvf" + (+ (f-op 5) mtrxg (f-ext 14) fvh fvf (f-rsvd 0)) + (c-call "sh64_ftrvs" (index-of mtrxg) (index-of fvh) (index-of fvf))) + +(dshmi getcfg "Get configuration register" + () + "getcfg $rm, $disp6, $rd" + (+ (f-op 48) rm (f-ext 15) disp6 rd (f-rsvd 0)) + (unimp "getcfg")) + +(dshmi getcon "Get control register" + () + "getcon $crk, $rd" + (+ (f-op 9) crk (f-ext 15) (f-right 63) rd (f-rsvd 0)) + (set rd crk)) + +(dshmi gettr "Get target register" + () + "gettr $trb, $rd" + (+ (f-op 17) (f-25 0) trb (f-ext 5) (f-right 63) rd (f-rsvd 0)) + (set rd trb)) + +(dshmi icbi "Invalidate instruction cache block" + () + "icbi $rm, $disp6x32" + (+ (f-op 56) rm (f-ext 5) disp6x32 (f-dest 63) (f-rsvd 0)) + (unimp "icbi")) + +(dshmi ldb "Load byte" + () + "ld.b $rm, $disp10, $rd" + (+ (f-op 32) rm disp10 rd (f-rsvd 0)) + (set rd (ext DI (mem QI (add rm (ext DI disp10)))))) + +(dshmi ldl "Load long word" + () + "ld.l $rm, $disp10x4, $rd" + (+ (f-op 34) rm disp10x4 rd (f-rsvd 0)) + (set rd (ext DI (mem SI (add rm (ext DI disp10x4)))))) + +(dshmi ldq "Load quad word" + () + "ld.q $rm, $disp10x8, $rd" + (+ (f-op 35) rm disp10x8 rd (f-rsvd 0)) + (set rd (mem DI (add rm (ext DI disp10x8))))) + +(dshmi ldub "Load unsigned byte" + () + "ld.ub $rm, $disp10, $rd" + (+ (f-op 36) rm disp10 rd (f-rsvd 0)) + (set rd (zext DI (mem QI (add rm (ext DI disp10)))))) + +(dshmi lduw "Load unsigned word" + () + "ld.uw $rm, $disp10x2, $rd" + (+ (f-op 44) rm disp10 rd (f-rsvd 0)) + (set rd (zext DI (mem HI (add rm (ext DI disp10x2)))))) + +(dshmi ldw "Load word" + () + "ld.w $rm, $disp10x2, $rd" + (+ (f-op 33) rm disp10 rd (f-rsvd 0)) + (set rd (ext DI (mem HI (add rm (ext DI disp10x2)))))) + +(dshmi ldhil "Load high part (long word)" + () + "ldhi.l $rm, $disp6, $rd" + (+ (f-op 48) rm (f-ext 6) disp6 rd (f-rsvd 0)) + ; FIXME. + (unimp "ldhil")) + +(dshmi ldhiq "Load high part (quad word)" + () + "ldhi.q $rm, $disp6, $rd" + (+ (f-op 48) rm (f-ext 7) disp6 rd (f-rsvd 0)) + ; FIXME. + (unimp "ldhiq")) + +(dshmi ldlol "Load low part (long word)" + () + "ldlo.l $rm, $disp6, $rd" + (+ (f-op 48) rm (f-ext 2) disp6 rd (f-rsvd 0)) + ; FIXME. + (unimp "ldlol")) + +(dshmi ldloq "Load low part (quad word)" + () + "ldlo.q $rm, $disp6, $rd" + (+ (f-op 48) rm (f-ext 3) disp6 rd (f-rsvd 0)) + ; FIXME; + (unimp "ldloq")) + +(dshmi ldxb "Load byte (extended displacement)" + () + "ldx.b $rm, $rn, $rd" + (+ (f-op 16) rm (f-ext 0) rn rd (f-rsvd 0)) + (set rd (ext DI (mem QI (add rm rn))))) + +(dshmi ldxl "Load long word (extended displacement)" + () + "ldx.l $rm, $rn, $rd" + (+ (f-op 16) rm (f-ext 2) rn rd (f-rsvd 0)) + (set rd (ext DI (mem SI (add rm rn))))) + +(dshmi ldxq "Load quad word (extended displacement)" + () + "ldx.q $rm, $rn, $rd" + (+ (f-op 16) rm (f-ext 3) rn rd (f-rsvd 0)) + (set rd (mem DI (add rm rn)))) + +(dshmi ldxub "Load unsigned byte (extended displacement)" + () + "ldx.ub $rm, $rn, $rd" + (+ (f-op 16) rm (f-ext 4) rn rd (f-rsvd 0)) + (set rd (zext DI (mem UQI (add rm rn))))) + +(dshmi ldxuw "Load unsigned word (extended displacement)" + () + "ldx.uw $rm, $rn, $rd" + (+ (f-op 16) rm (f-ext 5) rn rd (f-rsvd 0)) + (set rd (zext DI (mem UHI (add rm rn))))) + +(dshmi ldxw "Load word (extended displacement)" + () + "ldx.w $rm, $rn, $rd" + (+ (f-op 16) rm (f-ext 1) rn rd (f-rsvd 0)) + (set rd (ext DI (mem HI (add rm rn))))) + + +; Macros to facilitate multimedia instructions. + +(define-pmacro (slice-byte expr) + (sequence ((QI result7) (QI result6) (QI result5) (QI result4) + (QI result3) (QI result2) (QI result1) (QI result0)) + (set result0 (expr (subword QI rm 7) (subword QI rn 7))) + (set result1 (expr (subword QI rm 6) (subword QI rn 6))) + (set result2 (expr (subword QI rm 5) (subword QI rn 5))) + (set result3 (expr (subword QI rm 4) (subword QI rn 4))) + (set result4 (expr (subword QI rm 3) (subword QI rn 3))) + (set result5 (expr (subword QI rm 2) (subword QI rn 2))) + (set result6 (expr (subword QI rm 1) (subword QI rn 1))) + (set result7 (expr (subword QI rm 0) (subword QI rn 0))) + (set rd (-join-qi result7 result6 result5 result4 result3 result2 + result1 result0)))) + +(define-pmacro (slice-word expr) + (sequence ((HI result3) (HI result2) (HI result1) (HI result0)) + (set result0 (expr (subword HI rm 3) (subword HI rn 3))) + (set result1 (expr (subword HI rm 2) (subword HI rn 2))) + (set result2 (expr (subword HI rm 1) (subword HI rn 1))) + (set result3 (expr (subword HI rm 0) (subword HI rn 0))) + (set rd (-join-hi result3 result2 result1 result0)))) + +(define-pmacro (slice-word-unop expr) + (sequence ((HI result3) (HI result2) (HI result1) (HI result0)) + (set result0 (expr (subword HI rm 3))) + (set result1 (expr (subword HI rm 2))) + (set result2 (expr (subword HI rm 1))) + (set result3 (expr (subword HI rm 0))) + (set rd (-join-hi result3 result2 result1 result0)))) + +(define-pmacro (slice-long expr) + (sequence ((SI result1) (SI result0)) + (set result0 (expr (subword SI rm 1) (subword SI rn 1))) + (set result1 (expr (subword SI rm 0) (subword SI rn 0))) + (set rd (-join-si result1 result0)))) + +(define-pmacro (slice-long-unop expr) + (sequence ((SI result1) (SI result0)) + (set result0 (expr (subword SI rm 1))) + (set result1 (expr (subword SI rm 0))) + (set rd (-join-si result1 result0)))) + +; Multimedia instructions. + +(dshmi mabsl "Multimedia absolute value (long word)" + () + "mabs.l $rm, $rd" + (+ (f-op 10) rm (f-ext 10) (f-right 63) rd (f-rsvd 0)) + (slice-long-unop abs)) + +(dshmi mabsw "Multimedia absolute value (word)" + () + "mabs.w $rm, $rd" + (+ (f-op 10) rm (f-ext 9) (f-right 63) rd (f-rsvd 0)) + (slice-word-unop abs)) + +(dshmi maddl "Multimedia add (long word)" + () + "madd.l $rm, $rn, $rd" + (+ (f-op 2) rm (f-ext 2) rn rd (f-rsvd 0)) + (slice-long add)) + +(dshmi maddw "Multimedia add (word)" + () + "madd.w $rm, $rn, $rd" + (+ (f-op 2) rm (f-ext 1) rn rd (f-rsvd 0)) + (slice-word add)) + +(define-pmacro (-maddsl arg1 arg2) (saturate SI 32 (add arg1 arg2))) +(dshmi maddsl "Multimedia add (saturating, long word)" + () + "madds.l $rm, $rn, $rd" + (+ (f-op 2) rm (f-ext 6) rn rd (f-rsvd 0)) + (slice-long -maddsl)) + +(define-pmacro (-maddsub arg1 arg2) (usaturate QI 8 (add arg1 arg2))) +(dshmi maddsub "Multimedia add (saturating, unsigned byte)" + () + "madds.ub $rm, $rn, $rd" + (+ (f-op 2) rm (f-ext 4) rn rd (f-rsvd 0)) + (slice-byte -maddsub)) + +(define-pmacro (-maddsw arg1 arg2) (saturate HI 16 (add arg1 arg2))) +(dshmi maddsw "Multimedia add (saturating, word)" + () + "madds.w $rm, $rn, $rd" + (+ (f-op 2) rm (f-ext 5) rn rd (f-rsvd 0)) + (slice-word -maddsw)) + +(define-pmacro (-mcmpeq mode arg1 arg2) + (if mode (eq arg1 arg2) (inv mode 0) (const mode 0))) + +(define-pmacro (-mcmpeqb arg1 arg2) (-mcmpeq QI arg1 arg2)) +(dshmi mcmpeqb "Multimedia compare equal (byte)" + () + "mcmpeq.b $rm, $rn, $rd" + (+ (f-op 10) rm (f-ext 0) rn rd (f-rsvd 0)) + (slice-byte -mcmpeqb)) + +(define-pmacro (-mcmpeql arg1 arg2) (-mcmpeq SI arg1 arg2)) +(dshmi mcmpeql "Multimedia compare equal (long word)" + () + "mcmpeq.l $rm, $rn, $rd" + (+ (f-op 10) rm (f-ext 2) rn rd (f-rsvd 0)) + (slice-long -mcmpeql)) + +(define-pmacro (-mcmpeqw arg1 arg2) (-mcmpeq HI arg1 arg2)) +(dshmi mcmpeqw "Multimedia compare equal (word)" + () + "mcmpeq.w $rm, $rn, $rd" + (+ (f-op 10) rm (f-ext 1) rn rd (f-rsvd 0)) + (slice-word -mcmpeqw)) + +(define-pmacro (-mcmpgt mode arg1 arg2) + (if mode (gt arg1 arg2) (inv mode 0) (const mode 0))) +(define-pmacro (-mcmpgtu mode arg1 arg2) + (if mode (gtu arg1 arg2) (inv mode 0) (const mode 0))) + +(define-pmacro (-mcmpgtl arg1 arg2) (-mcmpgt SI arg1 arg2)) +(dshmi mcmpgtl "Multimedia compare greater than (long word)" + () + "mcmpgt.l $rm, $rn, $rd" + (+ (f-op 10) rm (f-ext 6) rn rd (f-rsvd 0)) + (slice-long -mcmpgtl)) + +(define-pmacro (-mcmpgtub arg1 arg2) (-mcmpgtu QI arg1 arg2)) +(dshmi mcmpgtub "Multimediate compare unsigned greater than (byte)" + () + "mcmpgt.ub $rm, $rn, $rd" + (+ (f-op 10) rm (f-ext 4) rn rd (f-rsvd 0)) + (slice-byte -mcmpgtub)) + +(define-pmacro (-mcmpgtw arg1 arg2) (-mcmpgt HI arg1 arg2)) +(dshmi mcmpgtw "Multimedia compare greater than (word)" + () + "mcmpgt.w $rm, $rn, $rd" + (+ (f-op 10) rm (f-ext 5) rn rd (f-rsvd 0)) + (slice-word -mcmpgtw)) + +(dshmi mcmv "Multimedia conditional move" + () + "mcmv $rm, $rn, $rd" + (+ (f-op 18) rm (f-ext 3) rn rd (f-rsvd 0)) + (set rd (or (and rm rn) (and rd (inv rn))))) + +(dshmi mcnvslw "Multimedia convert/saturate (long to word)" + () + "mcnvs.lw $rm, $rn, $rd" + (+ (f-op 19) rm (f-ext 13) rn rd (f-rsvd 0)) + (sequence ((HI result3) (HI result2) (HI result1) (HI result0)) + (set result0 (saturate HI 16 (subword SI rm 0))) + (set result1 (saturate HI 16 (subword SI rm 1))) + (set result2 (saturate HI 16 (subword SI rn 0))) + (set result3 (saturate HI 16 (subword SI rn 1))) + (set rd (-join-hi result3 result2 result1 result0)))) + +(dshmi mcnvswb "Multimedia convert/saturate (word to byte)" + () + "mcnvs.wb $rm, $rn, $rd" + (+ (f-op 19) rm (f-ext 8) rn rd (f-rsvd 0)) + (sequence ((QI result7) (QI result6) (QI result5) (QI result4) + (QI result3) (QI result2) (QI result1) (QI result0)) + (set result0 (saturate QI 8 (subword HI rm 0))) + (set result1 (saturate QI 8 (subword HI rm 1))) + (set result2 (saturate QI 8 (subword HI rm 2))) + (set result3 (saturate QI 8 (subword HI rm 3))) + (set result4 (saturate QI 8 (subword HI rn 0))) + (set result5 (saturate QI 8 (subword HI rn 1))) + (set result6 (saturate QI 8 (subword HI rn 2))) + (set result7 (saturate QI 8 (subword HI rn 3))) + (set rd (-join-qi result7 result6 result5 result4 + result3 result2 result1 result0)))) + +(dshmi mcnvswub "Multimedia convert/saturate (word to unsigned byte)" + () + "mcnvs.wub $rm, $rn, $rd" + (+ (f-op 19) rm (f-ext 12) rn rd (f-rsvd 0)) + (sequence ((QI result7) (QI result6) (QI result5) (QI result4) + (QI result3) (QI result2) (QI result1) (QI result0)) + (set result0 (usaturate QI 8 (subword HI rm 0))) + (set result1 (usaturate QI 8 (subword HI rm 1))) + (set result2 (usaturate QI 8 (subword HI rm 2))) + (set result3 (usaturate QI 8 (subword HI rm 3))) + (set result4 (usaturate QI 8 (subword HI rn 0))) + (set result5 (usaturate QI 8 (subword HI rn 1))) + (set result6 (usaturate QI 8 (subword HI rn 2))) + (set result7 (usaturate QI 8 (subword HI rn 3))) + (set rd (-join-qi result7 result6 result5 result4 result3 + result2 result1 result0)))) + +; mexter -- generate an mexterN instruction, where: +; op = primary opcode +; extop = extended opcode + +(define-pmacro (make-mextr n op extop) + (dshmi (.sym mextr n) + (.str "Multimedia extract 64-bit slice (from byte " n ")") + () + (.str "mextr" n " $rm, $rn, $rd") + (+ (f-op op) rm (f-ext extop) rn rd (f-rsvd 0)) + (sequence ((QI count) (DI mask) (DI rhs)) + (set count (mul QI 8 (sub QI 8 n))) + (set mask (sll DI (inv 0) count)) + (set rhs (srl (and rm mask) count)) + (set count (mul QI 8 n)) + (set mask (srl DI (inv 0) count)) + (set rd (or DI rhs (sll DI (and rn mask) count)))))) + +(make-mextr 1 10 7) +(make-mextr 2 10 11) +(make-mextr 3 10 15) +(make-mextr 4 11 3) +(make-mextr 5 11 7) +(make-mextr 6 11 11) +(make-mextr 7 11 15) + +(dshmi mmacfxwl "Multimedia fractional multiply (word to long)" + () + "mmacfx.wl $rm, $rn, $rd" + (+ (f-op 18) rm (f-ext 1) rn rd (f-rsvd 0)) + (sequence ((SI temp) (SI result1) (SI result0)) + (set result0 (subword SI rd 0)) + (set result1 (subword SI rd 1)) + (set temp (mul (zext SI (subword HI rm 0)) (zext SI (subword HI rn 0)))) + (set temp (saturate SI 32 (sll temp 1))) + (set result0 (saturate SI 32 (add result0 temp))) + (set temp (mul (zext SI (subword HI rm 1)) (zext SI (subword HI rn 1)))) + (set temp (saturate SI 32 (sll temp 1))) + (set result1 (saturate SI 32 (add result1 temp))) + (set rd (-join-si result1 result0)))) + +(dshmi mmacnfx.wl "Multimedia fractional multiple (word to long)" + () + "mmacnfx.wl $rm, $rn, $rd" + (+ (f-op 18) rn (f-ext 5) rn rd (f-rsvd 0)) + (sequence ((SI temp) (SI result1) (SI result0)) + (set result0 (subword SI rd 0)) + (set result1 (subword SI rd 1)) + (set temp (mul (zext SI (subword HI rm 0)) (zext SI (subword HI rn 0)))) + (set temp (saturate SI 32 (sll temp 1))) + (set result0 (saturate SI 32 (sub result0 temp))) + (set temp (mul (zext SI (subword HI rm 1)) (zext SI (subword HI rn 1)))) + (set temp (saturate SI 32 (sll temp 1))) + (set result1 (saturate SI 32 (sub result1 temp))) + (set rd (-join-si result1 result0)))) + +(dshmi mmull "Multimedia multiply (long word)" + () + "mmul.l $rm, $rn, $rd" + (+ (f-op 19) rm (f-ext 2) rn rd (f-rsvd 0)) + (slice-long mul)) + +(dshmi mmulw "Multimedia multiply (word)" + () + "mmul.w $rm, $rn, $rd" + (+ (f-op 19) rm (f-ext 1) rn rd (f-rsvd 0)) + (slice-word mul)) + +(dshmi mmulfxl "Multimedia fractional multiply (long word)" + () + "mmulfx.l $rm, $rn, $rd" + (+ (f-op 19) rm (f-ext 6) rn rd (f-rsvd 0)) + (sequence ((DI temp) (SI result0) (SI result1)) + (set temp (mul (zext DI (subword SI rm 0)) (zext DI (subword SI rn 0)))) + (set result0 (saturate SI 32 (sra temp 31))) + (set temp (mul (zext DI (subword SI rm 1)) (zext DI (subword SI rn 1)))) + (set result1 (saturate SI 32 (sra temp 31))) + (set rd (-join-si result1 result0)))) + +(dshmi mmulfxw "Multimedia fractional multiply (word)" + () + "mmulfx.w $rm, $rn, $rd" + (+ (f-op 19) rm (f-ext 5) rn rd (f-rsvd 0)) + (sequence ((SI temp) (HI result0) (HI result1) (HI result2) (HI result3)) + (set temp (mul (zext SI (subword HI rm 0)) (zext SI (subword HI rn 0)))) + (set result0 (saturate HI 16 (sra temp 15))) + (set temp (mul (zext SI (subword HI rm 1)) (zext SI (subword HI rn 1)))) + (set result1 (saturate HI 16 (sra temp 15))) + (set temp (mul (zext SI (subword HI rm 2)) (zext SI (subword HI rn 2)))) + (set result2 (saturate HI 16 (sra temp 15))) + (set temp (mul (zext SI (subword HI rm 3)) (zext SI (subword HI rn 3)))) + (set result3 (saturate HI 16 (sra temp 15))) + (set rd (-join-hi result3 result2 result1 result0)))) + +(dshmi mmulfxrpw "Multimedia fractional multiply round positive (word op)" + () + "mmulfxrp.w $rm, $rn, $rd" + (+ (f-op 19) rm (f-ext 9) rn rd (f-rsvd 0)) + (sequence ((SI temp) (HI result0) (HI result1) (HI result2) (HI result3) (HI c)) + (set c (sll 1 14)) + (set temp (mul (zext SI (subword HI rm 0)) (zext SI (subword HI rn 0)))) + (set result0 (saturate HI 16 (sra (add temp c) 15))) + (set temp (mul (zext SI (subword HI rm 1)) (zext SI (subword HI rn 1)))) + (set result1 (saturate HI 16 (sra (add temp c) 15))) + (set temp (mul (zext SI (subword HI rm 2)) (zext SI (subword HI rn 2)))) + (set result2 (saturate HI 16 (sra (add temp c) 15))) + (set temp (mul (zext SI (subword HI rm 3)) (zext SI (subword HI rn 3)))) + (set result3 (saturate HI 16 (sra (add temp c) 15))) + (set rd (-join-hi result3 result2 result1 result0)))) + +(dshmi mmulhiwl "Multimedia multiply higher halves (word to long)" + () + "mmulhi.wl $rm, $rn, $rd" + (+ (f-op 19) rm (f-ext 14) rn rd (f-rsvd 0)) + (sequence ((SI result1) (SI result0)) + (set result0 (mul (zext SI (subword HI rm 2)) (zext SI (subword HI rn 2)))) + (set result1 (mul (zext SI (subword HI rm 3)) (zext SI (subword HI rn 3)))) + (set rd (-join-si result1 result0)))) + +(dshmi mmullowl "Multimedia multiply lower halves (word to long)" + () + "mmullo.wl $rm, $rn, $rd" + (+ (f-op 19) rm (f-ext 10) rn rd (f-rsvd 0)) + (sequence ((SI result1) (SI result0)) + (set result0 (mul (zext SI (subword HI rm 0)) (zext SI (subword HI rn 0)))) + (set result1 (mul (zext SI (subword HI rm 1)) (zext SI (subword HI rn 1)))) + (set rd (-join-si result1 result0)))) + +(dshmi mmulsumwq "Multimedia multiply and accumulate (word to quad)" + () + "mmulsum.wq $rm, $rn, $rd" + (+ (f-op 18) rm (f-ext 9) rn rd (f-rsvd 0)) + (sequence ((DI acc)) + (set acc (mul SI (zext SI (subword HI rm 0)) (zext SI (subword HI rn 0)))) + (set acc (add acc (mul SI (zext SI (subword HI rm 1)) (zext SI (subword HI rn 1))))) + (set acc (add acc (mul SI (zext SI (subword HI rm 2)) (zext SI (subword HI rn 2))))) + (set acc (add acc (mul SI (zext SI (subword HI rm 3)) (zext SI (subword HI rn 3))))) + (set rd (add rd acc)))) + +(dshmi movi "Move immediate" + () + "movi $imm16, $rd" + (+ (f-op 51) imm16 rd (f-rsvd 0)) + (set rd (ext DI imm16))) + +(dshmi mpermw "Multimedia permutate word" + () + "mperm.w $rm, $rn, $rd" + (+ (f-op 10) rm (f-ext 13) rn rd (f-rsvd 0)) + (sequence ((QI control) (HI result3) (HI result2) (HI result1) (HI result0)) + (set control (and QI rn #x3f)) + (set result0 (subword HI rm (sub 3 (and control 3)))) + (set result1 (subword HI rm (sub 3 (and (srl control 2) 3)))) + (set result2 (subword HI rm (sub 3 (and (srl control 4) 3)))) + (set result3 (subword HI rm (sub 3 (and (srl control 6) 3)))) + (set rd (-join-hi result3 result2 result1 result0)))) + +(dshmi msadubq "Multimedia absolute difference (byte)" + () + "msad.ubq $rm, $rn, $rd" + (+ (f-op 18) rm (f-ext 0) rn rd (f-rsvd 0)) + (sequence ((DI acc)) + (set acc (abs DI (sub (subword QI rm 0) (subword QI rn 1)))) + (set acc (add DI acc (abs (sub (subword QI rm 1) (subword QI rn 1))))) + (set acc (add DI acc (abs (sub (subword QI rm 2) (subword QI rn 2))))) + (set acc (add DI acc (abs (sub (subword QI rm 3) (subword QI rn 3))))) + (set acc (add DI acc (abs (sub (subword QI rm 4) (subword QI rn 4))))) + (set acc (add DI acc (abs (sub (subword QI rm 5) (subword QI rn 5))))) + (set acc (add DI acc (abs (sub (subword QI rm 6) (subword QI rn 6))))) + (set acc (add DI acc (abs (sub (subword QI rm 7) (subword QI rn 7))))) + (set rd (add rd acc)))) + +(define-pmacro (-mshaldsl arg) (saturate SI 32 (sll arg (and rn 31)))) +(dshmi mshaldsl "Multimedia saturating arithmetic left shift (long word)" + () + "mshalds.l $rm, $rn, $rd" + (+ (f-op 3) rm (f-ext 6) rn rd (f-rsvd 0)) + (slice-long-unop -mshaldsl)) + +(define-pmacro (-mshaldsw arg) (saturate HI 16 (sll arg (and rn 15)))) +(dshmi mshaldsw "Multimedia saturating arithmetic left shift (word)" + () + "mshalds.w $rm, $rn, $rd" + (+ (f-op 3) rm (f-ext 5) rn rd (f-rsvd 0)) + (slice-word-unop -mshaldsw)) + +(define-pmacro (-mshardl arg) (sra arg (and rn 31))) +(dshmi mshardl "Multimedia arithmetic right shift (long)" + () + "mshard.l $rm, $rn, $rd" + (+ (f-op 3) rm (f-ext 10) rn rd (f-rsvd 0)) + (slice-long-unop -mshardl)) + +(define-pmacro (-mshardw arg) (sra arg (and rn 15))) +(dshmi mshardw "Multimedia arithmetic right shift (word)" + () + "mshard.w $rm, $rn, $rd" + (+ (f-op 3) rm (f-ext 9) rn rd (f-rsvd 0)) + (slice-word-unop -mshardw)) + +(dshmi mshardsq "Multimedia saturating arithmetic right shift (quad word)" + () + "mshards.q $rm, $rn, $rd" + (+ (f-op 3) rm (f-ext 11) rn rd (f-rsvd 0)) + (set rd (saturate DI 16 (sra rm (and rn 63))))) + +(dshmi mshfhib "Multimedia shuffle higher-half (byte)" + () + "mshfhi.b $rm, $rn, $rd" + (+ (f-op 11) rm (f-ext 4) rn rd (f-rsvd 0)) + (sequence ((QI result7) (QI result6) (QI result5) (QI result4) + (QI result3) (QI result2) (QI result1) (QI result0)) + (set result0 (subword QI rm 4)) + (set result1 (subword QI rn 4)) + (set result2 (subword QI rm 5)) + (set result3 (subword QI rn 5)) + (set result4 (subword QI rm 6)) + (set result5 (subword QI rn 6)) + (set result6 (subword QI rm 7)) + (set result7 (subword QI rn 7)) + (set rd (-join-qi result7 result6 result5 result4 result3 + result2 result1 result0)))) + +(dshmi mshfhil "Multimedia shuffle higher-half (long)" + () + "mshfhi.l $rm, $rn, $rd" + (+ (f-op 11) rm (f-ext 6) rn rd (f-rsvd 0)) + (sequence ((SI result1) (SI result0)) + (set result0 (subword SI rm 1)) + (set result1 (subword SI rn 1)) + (set rd (-join-si result1 result0)))) + +(dshmi mshfhiw "Multimedia shuffle higher-half (word)" + () + "mshfhi.w $rm, $rn, $rd" + (+ (f-op 11) rm (f-ext 5) rn rd (f-rsvd 0)) + (sequence ((HI result3) (HI result2) (HI result1) (HI result0)) + (set result0 (subword HI rm 2)) + (set result1 (subword HI rn 2)) + (set result2 (subword HI rm 3)) + (set result3 (subword HI rn 3)) + (set rd (-join-hi result3 result2 result1 result0)))) + +(dshmi mshflob "Multimedia shuffle lower-half (byte)" + () + "mshflo.b $rm, $rn, $rd" + (+ (f-op 11) rm (f-ext 0) rn rd (f-rsvd 0)) + (sequence ((QI result7) (QI result6) (QI result5) (QI result4) + (QI result3) (QI result2) (QI result1) (QI result0)) + (set result0 (subword QI rm 0)) + (set result1 (subword QI rn 0)) + (set result2 (subword QI rm 1)) + (set result3 (subword QI rn 1)) + (set result4 (subword QI rm 2)) + (set result5 (subword QI rn 2)) + (set result6 (subword QI rm 3)) + (set result7 (subword QI rn 3)) + (set rd (-join-qi result7 result6 result5 result4 result3 + result2 result1 result0)))) + +(dshmi mshflol "Multimedia shuffle lower-half (long)" + () + "mshflo.l $rm, $rn, $rd" + (+ (f-op 11) rm (f-ext 2) rn rd (f-rsvd 0)) + (sequence ((SI result1) (SI result0)) + (set result0 (subword SI rm 0)) + (set result1 (subword SI rn 0)) + (set rd (-join-si result1 result0)))) + +(dshmi mshflow "Multimedia shuffle lower-half (word)" + () + "mshflo.w $rm, $rn, $rd" + (+ (f-op 11) rm (f-ext 1) rn rd (f-rsvd 0)) + (sequence ((HI result3) (HI result2) (HI result1) (HI result0)) + (set result0 (subword HI rm 0)) + (set result1 (subword HI rn 0)) + (set result2 (subword HI rm 1)) + (set result3 (subword HI rn 1)) + (set rd (-join-hi result3 result2 result1 result0)))) + +(define-pmacro (-mshlldl arg) (sll arg (and rn 31))) +(dshmi mshlldl "Multimedia logical left shift (long word)" + () + "mshlld.l $rm, $rn, $rd" + (+ (f-op 3) rm (f-ext 2) rn rd (f-rsvd 0)) + (slice-long-unop -mshlldl)) + +(define-pmacro (-mshlldw arg) (sll arg (and rn 15))) +(dshmi mshlldw "Multimedia logical left shift (word)" + () + "mshlld.w $rm, $rn, $rd" + (+ (f-op 3) rm (f-ext 1) rn rd (f-rsvd 0)) + (slice-word-unop -mshlldw)) + +(define-pmacro (-mshlrdl arg) (srl arg (and rn 31))) +(dshmi mshlrdl "Multimedia logical right shift (long word)" + () + "mshlrd.l $rm, $rn, $rd" + (+ (f-op 3) rm (f-ext 14) rn rd (f-rsvd 0)) + (slice-long-unop -mshlrdl)) + +(define-pmacro (-mshlrdw arg) (srl arg (and rn 15))) +(dshmi mshlrdw "Multimedia logical right shift (word)" + () + "mshlrd.w $rm, $rn, $rd" + (+ (f-op 3) rm (f-ext 13) rn rd (f-rsvd 0)) + (slice-word-unop -mshlrdw)) + +(dshmi msubl "Multimedia subtract (long word)" + () + "msub.l $rm, $rn, $rd" + (+ (f-op 2) rm (f-ext 10) rn rd (f-rsvd 0)) + (slice-long sub)) + +(dshmi msubw "Multimedia add (word)" + () + "msub.w $rm, $rn, $rd" + (+ (f-op 2) rm (f-ext 9) rn rd (f-rsvd 0)) + (slice-word sub)) + +(define-pmacro (-msubsl arg1 arg2) (saturate SI 32 (sub arg1 arg2))) +(dshmi msubsl "Multimedia subtract (saturating long)" + () + "msubs.l $rm, $rn, $rd" + (+ (f-op 2) rm (f-ext 14) rn rd (f-rsvd 0)) + (slice-long -msubsl)) + +(define-pmacro (-msubsub arg1 arg2) (usaturate QI 8 (sub arg1 arg2))) +(dshmi msubsub "Multimedia subtract (saturating byte)" + () + "msubs.ub $rm, $rn, $rd" + (+ (f-op 2) rm (f-ext 12) rn rd (f-rsvd 0)) + (slice-byte -msubsub)) + +(define-pmacro (-msubsw arg1 arg2) (saturate HI 16 (sub arg1 arg2))) +(dshmi msubsw "Multimedia subtract (saturating word)" + () + "msubs.w $rm, $rn, $rd" + (+ (f-op 2) rm (f-ext 13) rn rd (f-rsvd 0)) + (slice-byte -msubsw)) + +(dshmi mulsl "Multiply signed long" + () + "muls.l $rm, $rn, $rd" + (+ (f-op 1) rm (f-ext 14) rn rd (f-rsvd 0)) + (set rd (mul (ext DI (subword SI rm 1)) (ext DI (subword SI rn 1))))) + +(dshmi mulul "Multiply unsigned long" + () + "mulu.l $rm, $rn, $rd" + (+ (f-op 0) rm (f-ext 14) rn rd (f-rsvd 0)) + (set rd (mul (zext DI (subword SI rm 1)) (zext DI (subword SI rn 1))))) + +(dshmi nop "No operation" + () + "nop" + (+ (f-op 27) (f-left 63) (f-ext 0) (f-right 63) (f-dest 63) (f-rsvd 0)) + (nop)) + +(dshmi nsb "Number of consecutive sign bits" + () + "nsb $rm, $rd" + (+ (f-op 0) rm (f-ext 13) (f-right 63) rd (f-rsvd 0)) + ; Semantics requires a loop construct, so punt to C. + (set rd (c-call DI "sh64_nsb" rm))) + +(dshmi ocbi "Invalidate operand cache block" + () + "ocbi $rm, $disp6x32" + (+ (f-op 56) rm (f-ext 9) disp6x32 (f-dest 63) (f-rsvd 0)) + (unimp "ocbi")) + +(dshmi ocbp "Purge operand cache block" + () + "ocbp $rm, $disp6x32" + (+ (f-op 56) rm (f-ext 8) disp6x32 (f-dest 63) (f-rsvd 0)) + (unimp "ocbp")) + +(dshmi ocbwb "Write-back operand cache block" + () + "ocbwb $rm, $disp6x32" + (+ (f-op 56) rm (f-ext 12) disp6x32 (f-dest 63) (f-rsvd 0)) + (unimp "ocbwb")) + +(dshmi or "OR" + () + "or $rm, $rn, $rd" + (+ (f-op 1) rm (f-ext 9) rn rd (f-rsvd 0)) + (set rd (or rm rn))) + +(dshmi ori "OR immediate" + () + "ori $rm, $imm10, $rd" + (+ (f-op 55) rm imm10 rd (f-rsvd 0)) + (set rd (or rm (ext DI imm10)))) + +(dshmi prefi "Prefetch instruction" + () + "prefi $rm, $disp6x32" + (+ (f-op 56) rm (f-ext 1) disp6x32 (f-right 63) (f-rsvd 0)) + (unimp "prefi")) + +(dshmi pta "Prepare target register for SHmedia target" + () + "pta$likely $disp16, $tra" + (+ (f-op 58) disp16 likely (f-8-2 0) tra (f-rsvd 0)) + (set tra (add disp16 1))) + +(dshmi ptabs "Prepare target register with absolute value from register" + () + "ptabs$likely $rn, $tra" + (+ (f-op 26) (f-left 63) (f-ext 1) rn likely (f-8-2 0) tra (f-rsvd 0)) + (set tra rn)) + +(dshmi ptb "Prepare target register for SHcompact target" + () + "ptb$likely $disp16, $tra" + (+ (f-op 59) disp16 likely (f-8-2 0) tra (f-rsvd 0)) + (set tra disp16)) + +(dshmi ptrel "Prepare target register with relative value from register" + () + "ptrel$likely $rn, $tra" + (+ (f-op 26) (f-left 63) (f-ext 5) rn likely (f-8-2 0) tra (f-rsvd 0)) + (set tra (add pc rn))) + +(dshmi putcfg "Put configuration register" + () + "putcfg $rm, $disp6, $rd" + (+ (f-op 56) rm (f-ext 15) disp6 rd (f-rsvd 0)) + (unimp "putcfg")) + +(dshmi putcon "Put control register" + () + "putcon $rm, $crj" + (+ (f-op 27) rm (f-ext 15) (f-right 63) crj (f-rsvd 0)) + (set crj rm)) + +(dshmi rte "Return from exception" + () + "rte" + (+ (f-op 27) (f-left 63) (f-ext 3) (f-right 63) (f-dest 63) (f-rsvd 0)) + (unimp "rte")) + +(dshmi shard "Arithmetic right shift" + () + "shard $rm, $rn, $rd" + (+ (f-op 1) rm (f-ext 7) rn rd (f-rsvd 0)) + (set rd (sra rm (and rn 63)))) + +(dshmi shardl "Arithmetic right shift (long word)" + () + "shard.l $rm, $rn, $rd" + (+ (f-op 1) rm (f-ext 6) rn rd (f-rsvd 0)) + (set rd (ext DI (sra (subword SI rm 1) (and rn 63))))) + +(dshmi shari "Arithmetic right shift (immediate count)" + () + "shari $rm, $uimm6, $rd" + (+ (f-op 49) rm (f-ext 7) uimm6 rd (f-rsvd 0)) + (set rd (sra rm uimm6))) + +(dshmi sharil "Arithmetic right shift (long word, immediate count)" + () + "shari.l $rm, $uimm6, $rd" + (+ (f-op 49) rm (f-ext 6) uimm6 rd (f-rsvd 0)) + (set rd (ext DI (sra (subword SI rm 1) (and uimm6 63))))) + +(dshmi shlld "Logical left shift" + () + "shlld $rm, $rn, $rd" + (+ (f-op 1) rm (f-ext 1) rn rd (f-rsvd 0)) + (set rd (sll rm (and rn 63)))) + +(dshmi shlldl "Logical left shift (long word)" + () + "shlld.l $rm, $rn, $rd" + (+ (f-op 1) rm (f-ext 0) rn rd (f-rsvd 0)) + (set rd (ext DI (sll (subword SI rm 1) (and rn 63))))) + +(dshmi shlli "Logical left shift (immediate count)" + () + "shlli $rm, $uimm6, $rd" + (+ (f-op 49) rm (f-ext 1) uimm6 rd (f-rsvd 0)) + (set rd (sll rm uimm6))) + +(dshmi shllil "Logical left shift (long word, immediate count)" + () + "shlli.l $rm, $uimm6, $rd" + (+ (f-op 49) rm (f-ext 0) uimm6 rd (f-rsvd 0)) + (set rd (ext DI (sll (subword SI rm 1) (and uimm6 63))))) + +(dshmi shlrd "Logical right shift" + () + "shlrd $rm, $rn, $rd" + (+ (f-op 1) rm (f-ext 3) rn rd (f-rsvd 0)) + (set rd (srl rm (and rn 63)))) + +(dshmi shlrdl "Logical right shift (long word)" + () + "shlrd.l $rm, $rn, $rd" + (+ (f-op 1) rm (f-ext 2) rn rd (f-rsvd 0)) + (set rd (ext DI (srl (subword SI rm 1) (and rn 63))))) + +(dshmi shlri "Logical right shift (immediate count)" + () + "shlri $rm, $uimm6, $rd" + (+ (f-op 49) rm (f-ext 3) uimm6 rd (f-rsvd 0)) + (set rd (srl rm uimm6))) + +(dshmi shlril "Logical right shift (long word, immediate count)" + () + "shlri.l $rm, $uimm6, $rd" + (+ (f-op 49) rm (f-ext 2) uimm6 rd (f-rsvd 0)) + (set rd (ext DI (srl (subword SI rm 1) (and uimm6 63))))) + +(dshmi shori "Shift-or immediate" + () + "shori $uimm16, $rd" + (+ (f-op 50) uimm16 rd (f-rsvd 0)) + (set rd (or (sll rd 16) (zext DI uimm16)))) + +(dshmi sleep "Sleep" + () + "sleep" + (+ (f-op 27) (f-left 63) (f-ext 7) (f-right 63) (f-dest 63) (f-rsvd 0)) + (unimp "sleep")) + +(dshmi stb "Store byte" + () + "st.b $rm, $disp10, $rd" + (+ (f-op 40) rm disp10 rd (f-rsvd 0)) + (set (mem UQI (add rm (ext DI disp10))) (and QI rd #xff))) + +(dshmi stl "Store long word" + () + "st.l $rm, $disp10x4, $rd" + (+ (f-op 42) rm disp10x4 rd (f-rsvd 0)) + (set (mem SI (add rm (ext DI disp10x4))) (and SI rd #xffffffff))) + +(dshmi stq "Store quad word" + () + "st.q $rm, $disp10x8, $rd" + (+ (f-op 43) rm disp10x8 rd (f-rsvd 0)) + (set (mem DI (add rm (ext DI disp10x8))) rd)) + +(dshmi stw "Store word" + () + "st.w $rm, $disp10x2, $rd" + (+ (f-op 41) rm disp10x2 rd (f-rsvd 0)) + (set (mem HI (add rm (ext DI disp10x2))) (and HI rd #xffff))) + +(define-pmacro (-sthi-byte) + (sequence () + (set (mem UQI addr) (and QI val #xff)) + (set val (srl val 8)) + (set addr (add addr 1)))) + +(dshmi sthil "Store high part (long word)" + () + "sthi.l $rm, $disp6, $rd" + (+ (f-op 56) rm (f-ext 6) disp6 rd (f-rsvd 0)) + (sequence ((DI addr) (QI bytecount) (DI val)) + (set addr (add rm disp6)) + (set bytecount (add (and addr 3) 1)) + (if endian + (set val rd) + (set val (srl rd (sub 32 (mul 8 bytecount))))) + (set addr (add (sub addr bytecount) 1)) + (if (gt bytecount 3) + (-sthi-byte)) + (if (gt bytecount 2) + (-sthi-byte)) + (if (gt bytecount 1) + (-sthi-byte)) + (if (gt bytecount 0) + (-sthi-byte)))) + +(dshmi sthiq "Store high part (quad word)" + () + "sthi.q $rm, $disp6, $rd" + (+ (f-op 56) rm (f-ext 7) disp6 rd (f-rsvd 0)) + (sequence ((DI addr) (QI bytecount) (DI val)) + (set addr (add rm disp6)) + (set bytecount (add (and addr 7) 1)) + (if endian + (set val rd) + (set val (srl rd (sub 64 (mul 8 bytecount))))) + (set addr (add (sub addr bytecount) 1)) + (if (gt bytecount 7) + (-sthi-byte)) + (if (gt bytecount 6) + (-sthi-byte)) + (if (gt bytecount 5) + (-sthi-byte)) + (if (gt bytecount 4) + (-sthi-byte)) + (if (gt bytecount 3) + (-sthi-byte)) + (if (gt bytecount 2) + (-sthi-byte)) + (if (gt bytecount 1) + (-sthi-byte)) + (if (gt bytecount 0) + (-sthi-byte)))) + +(dshmi stlol "Store low part (long word)" + () + "stlo.l $rm, $disp6, $rd" + (+ (f-op 56) rm (f-ext 2) disp6 rd (f-rsvd 0)) + ; FIXME. + (unimp "stlol")) + +(dshmi stloq "Store low part (quad word)" + () + "stlo.q $rm, $disp6, $rd" + (+ (f-op 56) rm (f-ext 3) disp6 rd (f-rsvd 0)) + ; FIXME. + (unimp "stloq")) + +(dshmi stxb "Store byte (extended displacement)" + () + "stx.b $rm, $rn, $rd" + (+ (f-op 24) rm (f-ext 0) rn rd (f-rsvd 0)) + (set (mem UQI (add rm rn)) (subword QI rd 7))) + +(dshmi stxl "Store long (extended displacement)" + () + "stx.l $rm, $rn, $rd" + (+ (f-op 24) rm (f-ext 2) rn rd (f-rsvd 0)) + (set (mem SI (add rm rn)) (subword SI rd 1))) + +(dshmi stxq "Store quad word (extended displacement)" + () + "stx.q $rm, $rn, $rd" + (+ (f-op 24) rm (f-ext 3) rn rd (f-rsvd 0)) + (set (mem DI (add rm rn)) rd)) + +(dshmi stxw "Store word (extended displacement)" + () + "stx.w $rm, $rn, $rd" + (+ (f-op 24) rm (f-ext 1) rn rd (f-rsvd 0)) + (set (mem HI (add rm rn)) (subword HI rd 3))) + +(dshmi sub "Subtract" + () + "sub $rm, $rn, $rd" + (+ (f-op 0) rm (f-ext 11) rn rd (f-rsvd 0)) + (set rd (sub rm rn))) + +(dshmi subl "Subtract long" + () + "sub.l $rm, $rn, $rd" + (+ (f-op 0) rm (f-ext 10) rn rd (f-rsvd 0)) + (set rd (ext DI (sub (subword SI rm 1) (subword SI rn 1))))) + +(dshmi swapq "Swap quad words" + () + "swap.q $rm, $rn, $rd" + (+ (f-op 8) rm (f-ext 3) rn rd (f-rsvd 0)) + (sequence ((DI addr) (DI temp)) + (set addr (add rm rn)) + (set temp (mem DI addr)) + (set (mem DI addr) rd) + (set rd temp))) + +(dshmi synci "Synchronise instruction fetch" + () + "synci" + (+ (f-op 27) (f-left 63) (f-ext 2) (f-right 63) (f-dest 63) (f-rsvd 0)) + (unimp "synci")) + +(dshmi synco "Synchronise data operations" + () + "synco" + (+ (f-op 27) (f-left 63) (f-ext 6) (f-right 63) (f-dest 63) (f-rsvd 0)) + (unimp "synco")) + +(dshmi trapa "Trap" + () + "trapa $rm" + (+ (f-op 27) rm (f-ext 1) (f-right 63) (f-dest 63) (f-rsvd 0)) + (c-call "sh64_trapa" rm pc)) + +(dshmi xor "Exclusive OR" + () + "xor $rm, $rn, $rd" + (+ (f-op 1) rm (f-ext 13) rn rd (f-rsvd 0)) + (set rd (xor rm rn))) + +(dshmi xori "Exclusive OR immediate" + () + "xori $rm, $imm6, $rd" + (+ (f-op 49) rm (f-ext 13) rn rd (f-rsvd 0)) + (set rd (xor rm (ext DI imm6)))) diff --git a/cpu/simplify.inc b/cpu/simplify.inc new file mode 100644 index 00000000000..808018dc83d --- /dev/null +++ b/cpu/simplify.inc @@ -0,0 +1,218 @@ +; Collection of macros, for GNU Binutils .cpu files. -*- Scheme -*- +; +; Copyright 2000, 2007, 2009 Free Software Foundation, Inc. +; +; Contributed by Red Hat Inc. +; +; 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. + +; Enums. + +; Define a normal enum without using name/value pairs. +; This is currently the same as define-full-enum but it needn't remain +; that way (it's define-full-enum that would change). + +(define-pmacro (define-normal-enum name comment attrs prefix vals) + "Define a normal enum, fixed number of arguments." + (define-full-enum name comment attrs prefix vals) +) + +; Define a normal insn enum. + +(define-pmacro (define-normal-insn-enum name comment attrs prefix fld vals) + "Define a normal instruction opcode enum." + (define-full-insn-enum name comment attrs prefix fld vals) +) + +; Instruction fields. + +; Normally, fields are unsigned and have no encode/decode needs. + +(define-pmacro (define-normal-ifield name comment attrs start length) + "Define a normal instruction field." + (define-full-ifield name comment attrs start length UINT #f #f) +) + +; For those who don't like typing. + +(define-pmacro (df name comment attrs start length mode encode decode) + "Shorthand form of normal fields requiring mode, encode/decode." + (define-full-ifield name comment attrs start length mode encode decode) +) +(define-pmacro dnf + "Shorthand form of define-normal-ifield." + define-normal-ifield +) + +; Define a normal multi-ifield. + +(define-pmacro (define-normal-multi-ifield name comment attrs + mode subflds insert extract) + "Define a normal multi-part instruction field." + (define-full-multi-ifield name comment attrs mode subflds insert extract) +) + +; For those who don't like typing. + +(define-pmacro dnmf + "Shorthand form of define-normal-multi-ifield." + define-normal-multi-ifield +) + +; Simple multi-ifields: mode is UINT, default insert/extract support, +; default encode/decode support. + +(define-pmacro (dsmf name comment attrs subflds) + "Define a simple multi-part instruction field." + (define-full-multi-ifield name comment attrs UINT subflds #f #f) +) + +; Hardware. + +; Simpler version for most hardware elements. +; Allow special assembler support specification but no semantic-name, +; getter/setter, or layout specs. + +(define-pmacro (define-normal-hardware name comment attrs type + indices values handlers) + "Define a normal hardware element." + (define-full-hardware name comment attrs name type + indices values handlers () () ()) +) + +; For those who don't like typing. + +(define-pmacro dnh + "Shorthand form of define-normal-hardware." + define-normal-hardware +) + +; Simpler version of dnh that leaves out the indices, values, handlers, +; getter/setter, and layout specs. +; This is useful for 1 bit registers. +; ??? While dsh and dnh aren't that distinguishable when perusing a .cpu file, +; they both take a fixed number of positional arguments, and dsh is a proper +; subset of dnh with all arguments in the same positions, so methinks things +; are ok. + +(define-pmacro (define-simple-hardware name comment attrs type) + "Define a simple hardware element (usually a scalar register)." + (define-full-hardware name comment attrs name type () () () () () ()) +) + +(define-pmacro dsh + "Shorthand form of define-simple-hardware." + define-simple-hardware +) + +; Operands. + +; Simpler version for most operands. +; Allow special assembler support specification but no handlers or +; getter/setter specs. + +(define-pmacro (define-normal-operand name comment attrs type index) + "Define a normal operand." + (define-full-operand name comment attrs type DFLT index () () ()) +) + +; For those who don't like typing. + +(define-pmacro dno + "Shorthand form of define-normal-operand." + define-normal-operand +) + +; Deprecated, but still in wide use. + +(define-pmacro dnop + "Shorthand form of define-normal-operand." + define-normal-operand +) + +(define-pmacro (dndo x-name x-mode x-args + x-syntax x-base-ifield x-encoding x-ifield-assertion + x-getter x-setter) + "Define a normal derived operand." + (define-derived-operand + (name x-name) + (mode x-mode) + (args x-args) + (syntax x-syntax) + (base-ifield x-base-ifield) + (encoding x-encoding) + (ifield-assertion x-ifield-assertion) + (getter x-getter) + (setter x-setter) + ) +) + +; Instructions. + +; Define an instruction object, normal version. +; At present all fields must be specified. +; Fields ifield-assertion is absent. + +(define-pmacro (define-normal-insn name comment attrs syntax fmt semantics timing) + "Define a normal instruction." + (define-full-insn name comment attrs syntax fmt () semantics timing) +) + +; To reduce the amount of typing. +; Note that this is the same name as the D'ni in MYST. Oooohhhh..... +; this must be the right way to go. :-) + +(define-pmacro dni + "Shorthand form of define-normal-insn." + define-normal-insn +) + +; Macro instructions. + +; Define a macro-insn object, normal version. +; This only supports expanding to one real insn. + +(define-pmacro (define-normal-macro-insn name comment attrs syntax expansion) + "Define a normal macro instruction." + (define-full-minsn name comment attrs syntax expansion) +) + +; To reduce the amount of typing. + +(define-pmacro dnmi + "Shorthand form of define-normal-macro-insn." + define-normal-macro-insn +) + +; Modes. +; ??? Not currently available for use. +; +; Define Normal Mode +; +;(define-pmacro (define-normal-mode name comment attrs bits bytes +; non-mode-c-type printf-type sem-mode ptr-to host?) +; "Define a normal mode.\n" +; (define-full-mode name comment attrs bits bytes +; non-mode-c-type printf-type sem-mode ptr-to host?) +;) +; +; For those who don't like typing. +;(define-pmacro dnm +; "Shorthand form of define-normal-mode.\n" +; define-normal-mode +;) diff --git a/cpu/xc16x.cpu b/cpu/xc16x.cpu new file mode 100644 index 00000000000..efa687d2b9f --- /dev/null +++ b/cpu/xc16x.cpu @@ -0,0 +1,3127 @@ +; Infineon XC16X CPU description. -*- Scheme -*- +; +; Copyright 2006, 2007, 2009 Free Software Foundation, Inc. +; +; Contributed by KPIT Cummins Infosystems Ltd.; developed under contract +; from Infineon Systems, GMBH , Germany. +; +; 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, 51 Franklin Street - Fifth Floor, Boston, MA +; 02110-1301, USA. + +(define-rtl-version 0 8) + +(include "simplify.inc") + +; define-arch appears first + +(define-arch + (name xc16x) ; name of cpu family + (comment "Infineon XC16X") + (default-alignment aligned) + (insn-lsb0? #t) + (machs xc16x) + (isas xc16x) +) + +; Attributes. +; An attribute to describe which pipeline an insn runs in generally OS. +(define-attr + (for insn) + (type enum) + (name PIPE) + (comment "parallel execution pipeline selection") + (values NONE OS) +) + +; Instruction set parameters. + +(define-isa + (name xc16x) + (default-insn-bitsize 32) + (base-insn-bitsize 32) + (default-insn-word-bitsize 16) + (decode-assist (15 14 13 12)) + ; The XC16X fetches 1 insn at a time. + (liw-insns 1) + (parallel-insns 1) +) + +; Cpu family definitions. + +(define-cpu + ; cpu names must be distinct from the architecture name and machine names. + ; The "b" suffix stands for "base" and is the convention. + ; The "f" suffix stands for "family" and is the convention. + (name xc16xbf) + (comment "Infineon XC16X base family") + (endian little) + (insn-chunk-bitsize 32) + (word-bitsize 16) + (parallel-insns 1) +) + +(define-mach + (name xc16x) + (comment "Infineon XC16X cpu") + (cpu xc16xbf) +) + +; Model descriptions. + +(define-model + (name xc16x) (comment "XC16X") (attrs) + (mach xc16x) + + (pipeline p-mem "" () ((prefetch) (fetch) (decode) (address) (memory) (execute) (writeback))) + + ; `state' is a list of variables for recording model state + (state + ; bit mask of h-gr registers, =1 means value being loaded from memory + (h-gr UINT) + ) + + (unit u-exec "Execution Unit" () + 1 1 ; issue done + () ; state + ((dr INT -1) (sr INT -1)) ; inputs + ((dr INT -1)) ; outputs + () ; profile action (default) + ) + (unit u-cmp "Compare Unit" () + 1 1 ; issue done + () ; state + ((src1 INT -1) (src2 INT -1)) ; inputs + () ; outputs + () ; profile action (default) + ) + (unit u-cti "Jump & Call Unit" () + 1 1 ; issue done + () ; state + ((condbit) (sr INT -1)) ; inputs + ((pc)) ; outputs + () ; profile action (default) + ) + (unit u-mov "Data Movement Unit" () + 1 1 ; issue done + () ;state + ((dr INT -1) (sr INT -1)) ; inputs + ((dr INT -1)) ; output + () ; profile action (default) + ) + ) + +; Instruction fields. +; +; Attributes: +; PCREL-ADDR: pc relative value (for reloc and disassembly purposes) +; ABS-ADDR: absolute address (for reloc and disassembly purposes) +; RELOC: there is a relocation associated with this field (experiment) + +(define-attr + (for ifield operand) + (type boolean) + (name RELOC) + (comment "there is a reloc associated with this field (experiment)") +) + +(dnf f-op1 "op1" () 7 4) +(dnf f-op2 "op2" () 3 4) +(dnf f-condcode "condcode" () 7 4) ;condition code required in other jmps and calls +(dnf f-icondcode "indrct condcode" () 15 4) ;condition code required in other jmpi and calli +(dnf f-rcond "relative-cond" () 7 4) ;condition code required in JMPR +(dnf f-qcond "qbit" () 7 4) ;used in enum of bset/bclear macro +(dnf f-extccode "extended condcode" () 15 5) ;condition code required in other jmpa and calla +(dnf f-r0 "r0" () 9 2) ;required where 2 bit register used(only R0-R3) +(dnf f-r1 "r1" () 15 4) +(dnf f-r2 "r2" () 11 4) +(dnf f-r3 "r3" () 12 4) +(dnf f-r4 "r4" () 11 4) +(dnf f-uimm2 "uimm2" () 13 2) ;used for immediate data,eg in ADD,MOV insns +(dnf f-uimm3 "uimm3" () 10 3) ;used for immediate data,eg in ADD,SUB insns +(dnf f-uimm4 "uimm4" () 15 4) ;used for immediate data,eg in MOV insns +(dnf f-uimm7 "uimm7" (PCREL-ADDR RELOC) 15 7) ;used in TRAP +(dnf f-uimm8 "uimm8" () 23 8) ;used in immediate byte data,eg in ADDB,MOVB insns +(dnf f-uimm16 "uimm16" () 31 16) ;used for immediate word data +(dnf f-memory "memory" () 31 16) ; used for memory operands +(dnf f-memgr8 "memory" () 31 16) ; memory location of gr +(dnf f-rel8 "rel8" (PCREL-ADDR RELOC) 15 8) ;used in JMPR,CALLR +(dnf f-relhi8 "relhi8" (PCREL-ADDR RELOC) 23 8) ;used in JB,JBC,JNB,JNBS +(dnf f-reg8 "reg8" () 15 8) ;required where 8bit gp register used +(dnf f-regmem8 "regmem8" () 15 8) ;required where 8bit register used +(dnf f-regoff8 "regoff8" () 15 8) ;required for offset calc +(dnf f-reghi8 "reghi8" () 23 8) ;required where 8bit register number used +(dnf f-regb8 "regb8" () 15 8) ;required for byte registers RL0,RH0, till RL8,RH8 +(dnf f-seg8 "seg8" () 15 8) ;used as segment number in JMPS,CALLS +(dnf f-segnum8 "segnum8" () 23 8) ;used in EXTS,EXTSR +(dnf f-mask8 "mask8" () 23 8) ;used as mask in BFLDH,BFLDL insns +(dnf f-pagenum "page num" () 25 10);used in EXTP,EXTPR +(dnf f-datahi8 "datahi8" () 31 8) ;used for filling with const data +(dnf f-data8 "data8" () 23 8) ;used for filling with const data +(dnf f-offset16 "address offset16" (ABS-ADDR RELOC) 31 16) ;used in JMPS,JMPA,CALLA,CALLS +(dnf f-op-bit1 "gap of 1 bit" () 11 1) ;used for filling with const data +(dnf f-op-bit2 "gap of 2 bits" () 11 2) ;used for filling with const data +(dnf f-op-bit4 "gap of 4 bits" () 11 4) ;used for filling with const data +(dnf f-op-bit3 "gap of 3 bits" () 10 3) ;used in CALLA, JMPA +(dnf f-op-2bit "gap of 2 bits" () 10 2) ;used in CALLA +(dnf f-op-bitone "gap of 1 bit " () 10 1) ;used in JMPA +(dnf f-op-onebit "gap of 1 bit " () 9 1) ;used in JMPA +(dnf f-op-1bit "gap of 1 bit " () 8 1) ;used in JMPA, CALLA +(dnf f-op-lbit4 "gap of 4 bits" () 15 4) ;used for filling with const data +(dnf f-op-lbit2 "gap of 2 bits" () 15 2) ;used for filling with const data +(dnf f-op-bit8 "gap of 8 bits" () 31 8) ;used for filling with const data +(dnf f-op-bit16 "gap of 16 bits" () 31 16) ;used for filling with const data +(dnf f-qbit "qbit" () 7 4) ;used in bit field of bset/bclear +(dnf f-qlobit "qlobit" () 31 4) ;used for filling with const data +(dnf f-qhibit "qhibit" () 27 4) ;used for filling with const data +(dnf f-qlobit2 "qlobit2" () 27 2) ;used for filling with const data +(dnf f-pof "upof16" () 31 16) ; used for memory operands + +; Enums. +; insn-op1: bits 0-3 +(define-normal-insn-enum insn-op1 "insn format enums" () OP1_ f-op1 + ("0" "1" "2" "3" "4" "5" "6" "7" + "8" "9" "10" "11" "12" "13" "14" "15") +) + +; insn-op2: bits 4-7 +(define-normal-insn-enum insn-op2 "op2 enums" () OP2_ f-op2 + ("0" "1" "2" "3" "4" "5" "6" "7" + "8" "9" "10" "11" "12" "13" "14" "15") +) + +;/*for bclr/bset*/ +; insn-rcond: bits 0-3 +(define-normal-insn-enum insn-qcond "bit set/clear enums" () QBIT_ f-qcond + (("0" 0) ("1" 1) ("2" 2) ("3" 3) ("4" 4) ("5" 5) ("6" 6) ("7" 7) ("8" 8) ("9" 9) ("10" 10) + ("11" 11) ("12" 12) ("13" 13) ("14" 14) ("15" 15)) +) +;/************/ +; insn-rcond: bits 0-3 +(define-normal-insn-enum insn-rcond "relative jump condition code op2 enums" () COND_ f-rcond + (("UC" 0) ("NET" 1) ("Z" 2) ("NE_NZ" 3) ("V" 4) ("NV" 5) ("N" 6) ("NN" 7) + ("C" 8) ("NC" 9) ("SGT" 10) ("SLE" 11) ("SLT" 12) ("SGE" 13) ("UGT" 14) ("ULE" 15) + ("EQ" 2) ("NE" 3) ("ULT" 8) ("UGE" 9)) +) + + + +; Hardware pieces. +; These entries list the elements of the raw hardware. +; They're also used to provide tables and other elements of the assembly +; language. + +(dnh h-pc "program counter" (PC) (pc) () () ()) + +(define-keyword + (name gr-names) + (enum-prefix H-GR-) + (values (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)) + +) +(define-hardware + (name h-gr) + (comment "general registers") + (attrs PROFILE CACHE-ADDR) + (type register HI (16)) + (indices extern-keyword gr-names) +) + +;; HACK: Various semantics refer to h-cr. +;; This is here to keep things working. +(define-hardware + (name h-cr) + (comment "cr registers") + (attrs PROFILE CACHE-ADDR) + (type register HI (16)) + (indices extern-keyword gr-names) +) + +(define-keyword + (name ext-names) + (enum-prefix H-EXT-) + (values (0x1 0) (0x2 1) (0x3 2) (0x4 3) + ("1" 0) ("2" 1) ("3" 2) ("4" 3)) + +) + +(define-hardware + (name h-ext) + (comment "ext values") + (attrs PROFILE CACHE-ADDR) + (type register HI (8)) + (indices extern-keyword ext-names) +) + +(define-keyword + (name psw-names) + (enum-prefix H-PSW-) + (values ("IEN" 136) ("r0.11" 240) ("r1.11" 241) ("r2.11" 242) ("r3.11" 243) ("r4.11" 244) + ("r5.11" 245) ("r6.11" 246) ("r7.11" 247) ("r8.11" 248) + ("r9.11" 249) ("r10.11" 250) ("r11.11" 251) ("r12.11" 252) + ("r13.11" 253) ("r14.11" 254) ("r15.11" 255)) +) + +(define-hardware + (name h-psw) + (comment "ext values") + (attrs PROFILE CACHE-ADDR) + (type register HI (1)) + (indices extern-keyword psw-names) +) + +(define-keyword + (name grb-names) + (enum-prefix H-GRB-) + (values (rl0 0) (rh0 1) (rl1 2) (rh1 3) (rl2 4) (rh2 5) (rl3 6) (rh3 7) + (rl4 8) (rh4 9) (rl5 10) (rh5 11) (rl6 12) (rh6 13) (rl7 14) (rh7 15)) +) + +(define-hardware + (name h-grb) + (comment "general registers") + (attrs PROFILE CACHE-ADDR) + (type register QI (16)) + (indices extern-keyword grb-names) +) + +(define-keyword + (name conditioncode-names) + (enum-prefix H-CC-) + (values (cc_UC 0) (cc_NET 1) (cc_Z 2) (cc_EQ 2) (cc_NZ 3) (cc_NE 3) (cc_V 4) (cc_NV 5) (cc_N 6) (cc_NN 7) (cc_ULT 8) (cc_UGE 9) + (cc_C 8) (cc_NC 9) (cc_SGT 10) (cc_SLE 11) (cc_SLT 12) (cc_SGE 13) (cc_UGT 14) + (cc_ULE 15)) +) +(define-hardware + (name h-cc) + (comment "condition codes") + (attrs PROFILE CACHE-ADDR) + (type register QI (16)) + (indices extern-keyword conditioncode-names) +) + +(define-keyword + (name extconditioncode-names) + (enum-prefix H-ECC-) + (values(cc_UC 0) (cc_NET 2) (cc_Z 4) (cc_EQ 4) (cc_NZ 6) (cc_NE 6) (cc_V 8) (cc_NV 10) (cc_N 12) (cc_NN 14) (cc_ULT 16) (cc_UGE 18) (cc_C 16) (cc_NC 18) (cc_SGT 20) + (cc_SLE 22) (cc_SLT 24) (cc_SGE 26) (cc_UGT 28) (cc_ULE 30) (cc_nusr0 1) + (cc_nusr1 3) (cc_usr0 5) (cc_usr1 7)) +) +(define-hardware + (name h-ecc) + (comment "extended condition codes") + (attrs PROFILE CACHE-ADDR) + (type register QI (4)) + (indices extern-keyword extconditioncode-names) +) + +(define-keyword + (name grb8-names) + (enum-prefix H-GRB8-) + (values (dpp0 0) (dpp1 1) (dpp2 2) (dpp3 3) + (psw 136) (cp 8) (mdl 7) (mdh 6) + (mdc 135) (sp 9) (csp 4) (vecseg 137) + (stkov 10) (stkun 11) (cpucon1 12) (cpucon2 13) + (zeros 142) (ones 143) (spseg 134) (tfr 214) + (rl0 240) (rh0 241) (rl1 242) (rh1 243) (rl2 244) (rh2 245) (rl3 246) (rh3 247) + (rl4 248) (rh4 249) (rl5 250) (rh5 251) (rl6 252) (rh6 253) (rl7 254) (rh7 255)) +) + +(define-hardware + (name h-grb8) + (comment "general byte registers") + (attrs PROFILE CACHE-ADDR) + (type register QI (36)) + (indices extern-keyword grb8-names) +) + +(define-keyword + (name r8-names) + (enum-prefix H-R8-) + (values (dpp0 0) (dpp1 1) (dpp2 2) (dpp3 3) + (psw 136) (cp 8) (mdl 7) (mdh 6) + (mdc 135) (sp 9) (csp 4) (vecseg 137) + (stkov 10) (stkun 11) (cpucon1 12) (cpucon2 13) + (zeros 142) (ones 143) (spseg 134) (tfr 214) + (r0 240) (r1 241) (r2 242) (r3 243) (r4 244) (r5 245) (r6 246) (r7 247) + (r8 248) (r9 249) (r10 250) (r11 251) (r12 252) (r13 253) (r14 254) (r15 255)) +) + +(define-hardware + (name h-r8) + (comment "registers") + (attrs PROFILE CACHE-ADDR) + (type register HI (36)) + (indices extern-keyword r8-names) +) + +(define-keyword + (name regmem8-names) + (enum-prefix H-REGMEM8-) + (values (dpp0 0) (dpp1 1) (dpp2 2) (dpp3 3) + (psw 136) (cp 8) (mdl 7) (mdh 6) + (mdc 135) (sp 9) (csp 4) (vecseg 137) + (stkov 10) (stkun 11) (cpucon1 12) (cpucon2 13) + (zeros 142) (ones 143) (spseg 134) (tfr 214) + (r0 240) (r1 241) (r2 242) (r3 243) (r4 244) (r5 245) (r6 246) (r7 247) + (r8 248) (r9 249) (r10 250) (r11 251) (r12 252) (r13 253) (r14 254) (r15 255)) +) + +(define-hardware + (name h-regmem8) + (comment "registers") + (attrs ) + (type register HI (16)) + (indices extern-keyword regmem8-names) +) + +(define-keyword + (name regdiv8-names) + (enum-prefix H-REGDIV8-) + (values (r0 0) (r1 17) (r2 34) (r3 51) (r4 68) (r5 85) (r6 102) (r7 119) + (r8 136) (r9 153) (r10 170) (r11 187) (r12 204) (r13 221) (r14 238) (r15 255)) +) + +(define-hardware + (name h-regdiv8) + (comment "division insn registers") + (attrs PROFILE CACHE-ADDR) + (type register HI (16)) + (indices extern-keyword regdiv8-names) +) + +(define-keyword + (name reg0-name) + (enum-prefix H-REG0-) + (values (0x1 1) (0x2 2) (0x3 3) (0x4 4) (0x5 5) (0x6 6) (0x7 7) (0x8 8) (0x9 9) (0xa 10) (0xb 11) + (0xc 12) (0xd 13) (0xe 14) (0xf 15) + ("1" 1) ("2" 2) ("3" 3) ("4" 4) ("5" 5) ("6" 6) ("7" 7) ("8" 8) ("9" 9) ("10" 10) ("11" 11) + ("12" 12) ("13" 13) ("14" 14) ("15" 15)) +) + +(define-hardware + (name h-r0) + (comment "for 4-bit data excuding 0") + (attrs PROFILE CACHE-ADDR) + (type register HI (30)) + (indices extern-keyword reg0-name) +) + +(define-keyword + (name reg0-name1) + (enum-prefix H-REG01-) + (values (0x1 1) (0x2 2) (0x3 3) (0x4 4) (0x5 5) (0x6 6) (0x7 7) + ("1" 1) ("2" 2) ("3" 3) ("4" 4) ("5" 5) ("6" 6) ("7" 7)) +) + +(define-hardware + (name h-r01) + (comment "for 4-bit data excuding 0") + (attrs PROFILE CACHE-ADDR) + (type register HI (14)) + (indices extern-keyword reg0-name1) +) + +(define-keyword + (name regbmem8-names) + (enum-prefix H-REGBMEM8-) + (values (dpp0 0) (dpp1 1) (dpp2 2) (dpp3 3) + (psw 136) (cp 8) (mdl 7) (mdh 6) + (mdc 135) (sp 9) (csp 4) (vecseg 137) + (stkov 10) (stkun 11) (cpucon1 12) (cpucon2 13) + (zeros 142) (ones 143) (spseg 134) (tfr 214) + (rl0 240) (rh0 241) (rl1 242) (rh1 243) (rl2 244) (rh2 245) (rl3 246) (rh3 247) + (rl4 248) (rh4 249) (rl5 250) (rh5 251) (rl6 252) (rh6 253) (rl7 254) (rh7 255)) +) + +(define-hardware + (name h-regbmem8) + (comment "registers") + (attrs PROFILE CACHE-ADDR) + (type register HI (36)) + (indices extern-keyword regbmem8-names) +) + +(define-keyword + (name memgr8-names) + (enum-prefix H-MEMGR8-) + (values (dpp0 65024) (dpp1 65026) (dpp2 65028) (dpp3 65030) + (psw 65296) (cp 65040) (mdl 65038) (mdh 65036) + (mdc 65294) (sp 65042) (csp 65032) (vecseg 65298) + (stkov 65044) (stkun 65046) (cpucon1 65048) (cpucon2 65050) + (zeros 65308) (ones 65310) (spseg 65292) (tfr 65452) ) +) + +(define-hardware + (name h-memgr8) + (comment "memory location of registers") + (attrs ) + (type register HI (20)) + (indices extern-keyword memgr8-names) +) + +(dsh h-cond "condition bit" () (register BI)) ;any bit from PSW while comparison +; This bit is part of the PSW register +(dsh h-cbit "carry bit" () (register BI)) + +(dsh h-sgtdis "segmentation enable bit" () (register BI)) ;0 means segmentation enabled + +;Instruction operands +; -- layer between the assembler and the raw hardware description +; -- the main means of manipulating instruction fields in the semantic code + +; XC16X specific operand attributes: + +(define-attr + (for operand) + (type boolean) + (name HASH-PREFIX) + (comment "immediates have an optional '#' prefix") +) + +(define-attr + (for operand) + (type boolean) + (name DOT-PREFIX) + (comment "bit addr have an optional '.' prefix") +) + +(define-attr + (for operand) + (type boolean) + (name POF-PREFIX) + (comment "page offset ") +) + +(define-attr + (for operand) + (type boolean) + (name PAG-PREFIX) + (comment "page ") +) + +(define-attr + (for operand) + (type boolean) + (name SOF-PREFIX) + (comment "segment offset selection") +) + +(define-attr + (for operand) + (type boolean) + (name SEG-PREFIX) + (comment "segment") +) + +(dnop sr "source register" () h-gr f-r2) +(dnop dr "destination register" () h-gr f-r1) +(dnop dri "destination register" () h-gr f-r4) +(dnop srb "source register" () h-grb f-r2) +(dnop drb "destination register" () h-grb f-r1) +(dnop sr2 "2 bit source register" () h-gr f-r0) +(dnop src1 "source register 1" () h-gr f-r1) +(dnop src2 "source register 2" () h-gr f-r2) +(dnop srdiv "source register 2" () h-regdiv8 f-reg8) +(dnop RegNam "PSW bits" () h-psw f-reg8) +(dnop uimm2 "2 bit unsigned number" (HASH-PREFIX) h-ext f-uimm2) +(dnop uimm3 "3 bit unsigned number" (HASH-PREFIX) h-r01 f-uimm3) +(dnop uimm4 "4 bit unsigned number" (HASH-PREFIX) h-uint f-uimm4) +(dnop uimm7 "7 bit trap number" (HASH-PREFIX) h-uint f-uimm7) +(dnop uimm8 "8 bit unsigned immediate" (HASH-PREFIX) h-uint f-uimm8) +(dnop uimm16 "16 bit unsigned immediate" (HASH-PREFIX) h-uint f-uimm16) +(dnop upof16 "16 bit unsigned immediate" (POF-PREFIX) h-addr f-memory) +(dnop reg8 "8 bit word register number" () h-r8 f-reg8) +(dnop regmem8 "8 bit word register number" () h-regmem8 f-regmem8) +(dnop regbmem8 "8 bit byte register number" () h-regbmem8 f-regmem8) +(dnop regoff8 "8 bit word register number" () h-r8 f-regoff8) +(dnop reghi8 "8 bit word register number" () h-r8 f-reghi8) +(dnop regb8 "8 bit byte register number" () h-grb8 f-regb8) +(dnop genreg "8 bit word register number" () h-r8 f-regb8) +(dnop seg "8 bit segment number" () h-uint f-seg8) +(dnop seghi8 "8 bit hi segment number" () h-uint f-segnum8) +(dnop caddr "16 bit address offset" () h-addr f-offset16) +(dnop rel "8 bit signed relative offset" () h-sint f-rel8) +(dnop relhi "hi 8 bit signed relative offset" () h-sint f-relhi8) +(dnop condbit "condition bit" (SEM-ONLY) h-cond f-nil) +(dnop bit1 "gap of 1 bit" () h-uint f-op-bit1) +(dnop bit2 "gap of 2 bits" () h-uint f-op-bit2) +(dnop bit4 "gap of 4 bits" () h-uint f-op-bit4) +(dnop lbit4 "gap of 4 bits" () h-uint f-op-lbit4) +(dnop lbit2 "gap of 2 bits" () h-uint f-op-lbit2) +(dnop bit8 "gap of 8 bits" () h-uint f-op-bit8) +(dnop u4 "gap of 4 bits" () h-r0 f-uimm4) +(dnop bitone "field of 1 bit" () h-uint f-op-onebit) +(dnop bit01 "field of 1 bit" () h-uint f-op-1bit) +(dnop cond "condition code" () h-cc f-condcode) +(dnop icond "indirect condition code" () h-cc f-icondcode) +(dnop extcond "extended condition code" () h-ecc f-extccode) +(dnop memory "16 bit memory" () h-addr f-memory) +(dnop memgr8 "16 bit memory" () h-memgr8 f-memgr8) +(dnop cbit "carry bit" (SEM-ONLY) h-cbit f-nil) +(dnop qbit "bit addr" (DOT-PREFIX) h-uint f-qbit) +(dnop qlobit "bit addr" (DOT-PREFIX) h-uint f-qlobit) +(dnop qhibit "bit addr" (DOT-PREFIX) h-uint f-qhibit) +(dnop mask8 "8 bit mask" (HASH-PREFIX) h-uint f-mask8) +(dnop masklo8 "8 bit mask" (HASH-PREFIX) h-uint f-datahi8) +(dnop pagenum "10 bit page number" (HASH-PREFIX) h-uint f-pagenum) +(dnop data8 "8 bit data" (HASH-PREFIX) h-uint f-data8) +(dnop datahi8 "8 bit data" (HASH-PREFIX) h-uint f-datahi8) +(dnop sgtdisbit "segmentation enable bit" (SEM-ONLY) h-sgtdis f-nil) +(dnop upag16 "16 bit unsigned immediate" (PAG-PREFIX) h-uint f-uimm16) +(dnop useg8 "8 bit segment " (SEG-PREFIX) h-uint f-seg8) +(dnop useg16 "16 bit address offset" (SEG-PREFIX) h-uint f-offset16) +(dnop usof16 "16 bit address offset" (SOF-PREFIX) h-uint f-offset16) + +; define hash operator +(define-operand (name hash) (comment "# prefix") (attrs) + (type h-sint) + (index f-nil) + (handlers (parse "hash") (print "hash")) +) + +; define dot operator +(define-operand (name dot) (comment ". prefix") (attrs) + (type h-sint) + (index f-nil) + (handlers (parse "dot") (print "dot")) +) + +; define pof operator +(define-operand (name pof) (comment "pof: prefix") (attrs) + (type h-sint) + (index f-nil) + (handlers (parse "pof") (print "pof")) +) + +; define pag operator +(define-operand (name pag) (comment "pag: prefix") (attrs) + (type h-sint) + (index f-nil) + (handlers (parse "pag") (print "pag")) +) + +; define sof operator +(define-operand (name sof) (comment "sof: prefix") (attrs) + (type h-sint) + (index f-nil) + (handlers (parse "sof") (print "sof")) +) + +; define seg operator +(define-operand (name segm) (comment "seg: prefix") (attrs) + (type h-sint) + (index f-nil) + (handlers (parse "seg") (print "seg")) +) + +; IDOC attribute for instruction documentation. +(define-attr + (for insn) + (type enum) + (name IDOC) + (comment "insn kind for documentation") + (attrs META) + (values + (MOVE - () "Data Movement") + (ALU - () "Arithmatic & logical") + (CMP - () "Compare") + (JMP - () "Jump & Call") + (MISC - () "Miscellaneous") + (SYSC - () "System control") + ) +) + +; Include the instruction set descriptions from their respective +; source files. + +;Arithmatic insns +;****************************************************************** + +;add/sub register and immediate +(define-pmacro (arithmetic16 name insn insn1 opc1 opc2 op1 op2 mode dir) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$"dir"$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (insn1 mode op1 (mem HI op2))) + () + ) +) +(arithmetic16 addrpof add add OP1_0 OP2_2 reg8 upof16 HI "pof") +(arithmetic16 subrpof sub sub OP1_2 OP2_2 reg8 upof16 HI "pof") +(arithmetic16 addbrpof addb add OP1_0 OP2_3 regb8 upof16 QI "pof") +(arithmetic16 subbrpof subb sub OP1_2 OP2_3 regb8 upof16 QI "pof") +(arithmetic16 addrpag add add OP1_0 OP2_2 reg8 upag16 HI "pag") +(arithmetic16 subrpag sub sub OP1_2 OP2_2 reg8 upag16 HI "pag") +(arithmetic16 addbrpag addb add OP1_0 OP2_3 regb8 upag16 QI "pag") +(arithmetic16 subbrpag subb sub OP1_2 OP2_3 regb8 upag16 QI "pag") + +;add/sub register and immediate +(define-pmacro (arithmetic17 name insn insn1 opc1 opc2 op1 op2 mode dir) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$"dir"$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (insn1 mode op1 (mem HI op2) cbit)) + () + ) +) +(arithmetic17 addcrpof addc addc OP1_1 OP2_2 reg8 upof16 HI "pof") +(arithmetic17 subcrpof subc subc OP1_3 OP2_2 reg8 upof16 HI "pof") +(arithmetic17 addcbrpof addcb addc OP1_1 OP2_3 regb8 upof16 QI "pof") +(arithmetic17 subcbrpof subcb subc OP1_3 OP2_3 regb8 upof16 QI "pof") +(arithmetic17 addcrpag addc addc OP1_1 OP2_2 reg8 upag16 HI "pag") +(arithmetic17 subcrpag subc subc OP1_3 OP2_2 reg8 upag16 HI "pag") +(arithmetic17 addcbrpag addcb addc OP1_1 OP2_3 regb8 upag16 QI "pag") +(arithmetic17 subcbrpag subcb subc OP1_3 OP2_3 regb8 upag16 QI "pag") + +;add/sub register and immediate +(define-pmacro (arithmetic18 name insn insn1 opc1 opc2 op1 op2 mode dir) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"dir"$"op1 ",$"op2) + (+ opc1 opc2 op2 op1) + (set (mem HI op1) (insn1 (mem HI op1) op2 )) + () + ) +) +(arithmetic18 addrpofr add add OP1_0 OP2_4 upof16 reg8 HI "pof") +(arithmetic18 subrpofr sub sub OP1_2 OP2_4 upof16 reg8 HI "pof") +(arithmetic18 addbrpofr addb add OP1_0 OP2_5 upof16 regb8 QI "pof") +(arithmetic18 subbrpofr subb sub OP1_2 OP2_5 upof16 regb8 QI "pof") + +;add/sub register and immediate +(define-pmacro (arithmetic19 name insn insn1 opc1 opc2 op1 op2 mode dir) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"dir"$"op1 ",$"op2) + (+ opc1 opc2 op2 op1) + (set (mem HI op1) (insn1 mode (mem HI op1) op2 cbit)) + () + ) +) +(arithmetic19 addcrpofr addc addc OP1_1 OP2_4 upof16 reg8 HI "pof") +(arithmetic19 subcrpofr subc subc OP1_3 OP2_4 upof16 reg8 HI "pof") +(arithmetic19 addcbrpofr addcb addc OP1_1 OP2_5 upof16 regb8 QI "pof") +(arithmetic19 subcbrpofr subcb subc OP1_3 OP2_5 upof16 regb8 QI "pof") + +;add/sub register and immediate +(define-pmacro (arithmetic20 name insn insn1 opc1 opc2 op1 op2 mode dir) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"dir"$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (insn1 mode op1 op2)) + () + ) +) +(arithmetic20 addrhpof add add OP1_0 OP2_6 reg8 uimm16 HI "pof") +(arithmetic20 subrhpof sub sub OP1_2 OP2_6 reg8 uimm16 HI "pof") +(arithmetic20 addbrhpof add add OP1_0 OP2_6 reg8 uimm16 HI "pag") +(arithmetic20 subbrhpof sub sub OP1_2 OP2_6 reg8 uimm16 HI "pag") + +;add/sub register and immediate +(define-pmacro (arithmetic21 name insn insn1 opc1 opc2 op1 op2 mode dir) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"dir"$"op2) + (+ opc1 opc2 op1 (f-op-bit1 0) op2) + (set mode op1 (insn1 mode op1 op2)) + () + ) +) +(arithmetic21 addrhpof3 add add OP1_0 OP2_8 dr uimm3 HI "pof") +(arithmetic21 subrhpof3 sub sub OP1_2 OP2_8 dr uimm3 HI "pof") +(arithmetic21 addbrhpag3 addb add OP1_0 OP2_9 drb uimm3 QI "pag") +(arithmetic21 subbrhpag3 subb sub OP1_2 OP2_9 drb uimm3 QI "pag") +(arithmetic21 addrhpag3 add add OP1_0 OP2_8 dr uimm3 HI "pag") +(arithmetic21 subrhpag3 sub sub OP1_2 OP2_8 dr uimm3 HI "pag") +(arithmetic21 addbrhpof3 addb add OP1_0 OP2_9 drb uimm3 QI "pof") +(arithmetic21 subbrhpof3 subb sub OP1_2 OP2_9 drb uimm3 QI "pof") + +;add/sub register and immediate +(define-pmacro (arithmetic22 name insn insn1 opc1 opc2 op1 op2 mode dir) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"dir"$"op2) + (+ opc1 opc2 op1 op2 (f-op-bit8 0)) + (set mode op1 (insn1 mode op1 op2)) + () + ) +) +(arithmetic22 addrbhpof addb add OP1_0 OP2_7 regb8 uimm8 QI "pof") +(arithmetic22 subrbhpof subb sub OP1_2 OP2_7 regb8 uimm8 QI "pof") +(arithmetic22 addbrhpag addb add OP1_0 OP2_7 regb8 uimm8 QI "pag") +(arithmetic22 subbrhpag subb sub OP1_2 OP2_7 regb8 uimm8 QI "pag") + +;add/sub register and immediate +(define-pmacro (arithmetic23 name insn insn1 opc1 opc2 op1 op2 mode dir) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"dir"$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (insn1 mode op1 op2 cbit)) + () + ) +) +(arithmetic23 addcrhpof addc addc OP1_1 OP2_6 reg8 uimm16 HI "pof") +(arithmetic23 subcrhpof subc subc OP1_3 OP2_6 reg8 uimm16 HI "pof") +(arithmetic23 addcbrhpof addc addc OP1_1 OP2_6 reg8 uimm16 HI "pag") +(arithmetic23 subcbrhpof subc subc OP1_3 OP2_6 reg8 uimm16 HI "pag") + +;add/sub register and immediate +(define-pmacro (arithmetic24 name insn insn1 opc1 opc2 op1 op2 mode dir) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"dir"$"op2) + (+ opc1 opc2 op1 (f-op-bit1 0) op2) + (set mode op1 (insn1 mode op1 op2 cbit)) + () + ) +) +(arithmetic24 addcrhpof3 addc addc OP1_1 OP2_8 dr uimm3 HI "pof") +(arithmetic24 subcrhpof3 subc subc OP1_3 OP2_8 dr uimm3 HI "pof") +(arithmetic24 addcbrhpag3 addcb addc OP1_1 OP2_9 drb uimm3 QI "pag") +(arithmetic24 subcbrhpag3 subcb subc OP1_3 OP2_9 drb uimm3 QI "pag") +(arithmetic24 addcrhpag3 addc addc OP1_1 OP2_8 dr uimm3 HI "pag") +(arithmetic24 subcrhpag3 subc subc OP1_3 OP2_8 dr uimm3 HI "pag") +(arithmetic24 addcbrhpof3 addcb addc OP1_1 OP2_9 drb uimm3 QI "pof") +(arithmetic24 subcbrhpof3 subcb subc OP1_3 OP2_9 drb uimm3 QI "pof") + +;add/sub register and immediate +(define-pmacro (arithmetic25 name insn insn1 opc1 opc2 op1 op2 mode dir) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"dir"$"op2) + (+ opc1 opc2 op1 op2 (f-op-bit8 0)) + (set mode op1 (insn1 mode op1 op2 cbit)) + () + ) +) +(arithmetic25 addcrbhpof addcb addc OP1_1 OP2_7 regb8 uimm8 QI "pof") +(arithmetic25 subcrbhpof subcb subc OP1_3 OP2_7 regb8 uimm8 QI "pof") +(arithmetic25 addcbrhpag addcb addc OP1_1 OP2_7 regb8 uimm8 QI "pag") +(arithmetic25 subcbrhpag subcb subc OP1_3 OP2_7 regb8 uimm8 QI "pag") + +;add/sub register and immediate +(define-pmacro (arithmetic10 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"op2) + (+ opc1 opc2 op1 (f-op-bit1 0) op2) + (set mode op1 (insn1 mode op1 op2)) + () + ) +) +(arithmetic10 addri add add OP1_0 OP2_8 dr uimm3 HI) +(arithmetic10 subri sub sub OP1_2 OP2_8 dr uimm3 HI) +(arithmetic10 addbri addb add OP1_0 OP2_9 drb uimm3 QI) +(arithmetic10 subbri subb sub OP1_2 OP2_9 drb uimm3 QI) + +;add/sub register and immediate +(define-pmacro (arithmetic11 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (insn1 mode op1 op2)) + () + ) +) +(arithmetic11 addrim add add OP1_0 OP2_6 reg8 uimm16 HI) +(arithmetic11 subrim sub sub OP1_2 OP2_6 reg8 uimm16 HI) + +;add/sub register and immediate +(define-pmacro (arithmetic12 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"op2) + (+ opc1 opc2 op1 op2 (f-op-bit8 0)) + (set mode op1 (insn1 mode op1 op2)) + () + ) +) +(arithmetic12 addbrim addb add OP1_0 OP2_7 regb8 uimm8 QI) +(arithmetic12 subbrim subb sub OP1_2 OP2_7 regb8 uimm8 QI) + +;add/sub register and immediate with carry +(define-pmacro (arithmetic13 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"op2) + (+ opc1 opc2 op1 (f-op-bit1 0) op2) + (set mode op1 (insn1 mode op1 op2 cbit)) + () + ) +) +(arithmetic13 addcri addc addc OP1_1 OP2_8 dr uimm3 HI) +(arithmetic13 subcri subc subc OP1_3 OP2_8 dr uimm3 HI) +(arithmetic13 addcbri addcb addc OP1_1 OP2_9 drb uimm3 QI) +(arithmetic13 subcbri subcb subc OP1_3 OP2_9 drb uimm3 QI) + +;add/sub register and immediate with carry +(define-pmacro (arithmetic14 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (insn1 mode op1 op2 cbit)) + () + ) +) +(arithmetic14 addcrim addc addc OP1_1 OP2_6 reg8 uimm16 HI) +(arithmetic14 subcrim subc subc OP1_3 OP2_6 reg8 uimm16 HI) + +;add/sub register and immediate with carry +(define-pmacro (arithmetic15 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"op2) + (+ opc1 opc2 op1 op2 (f-op-bit8 0)) + (set mode op1 (insn1 mode op1 op2 cbit)) + () + ) +) +(arithmetic15 addcbrim addcb addc OP1_1 OP2_7 regb8 uimm8 QI) +(arithmetic15 subcbrim subcb subc OP1_3 OP2_7 regb8 uimm8 QI) + + +;add/sub registers +(define-pmacro (arithmetic name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (insn1 mode op1 op2)) + () + ) +) +(arithmetic addr add add OP1_0 OP2_0 dr sr HI) +(arithmetic subr sub sub OP1_2 OP2_0 dr sr HI) +(arithmetic addbr addb add OP1_0 OP2_1 drb srb QI) +(arithmetic subbr subb sub OP1_2 OP2_1 drb srb QI) + +;add/sub register and indirect memory +(define-pmacro (arithmetic1 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",[$"op2"]") + (+ opc1 opc2 op1 (f-op-bit2 2) op2) + (set mode op1 (insn1 mode op1 (mem HI op2))) + () + ) +) +(arithmetic1 add2 add add OP1_0 OP2_8 dr sr2 HI) +(arithmetic1 sub2 sub sub OP1_2 OP2_8 dr sr2 HI) +(arithmetic1 addb2 addb add OP1_0 OP2_9 drb sr2 QI) +(arithmetic1 subb2 subb sub OP1_2 OP2_9 drb sr2 QI) + +;add/sub register and indirect memory post increment +(define-pmacro (arithmetic2 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",[$"op2"+]") + (+ opc1 opc2 op1 (f-op-bit2 3) op2) + (sequence () + (set mode op1 (insn1 mode op1 (mem HI op2))) + (set HI op2 (add HI op2 (const 2))) + ) + () + ) +) +(arithmetic2 add2i add add OP1_0 OP2_8 dr sr2 HI) +(arithmetic2 sub2i sub sub OP1_2 OP2_8 dr sr2 HI) +(arithmetic2 addb2i addb add OP1_0 OP2_9 drb sr2 QI) +(arithmetic2 subb2i subb sub OP1_2 OP2_9 drb sr2 QI) + +;add/sub registers with carry +(define-pmacro (arithmetic3 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (insn1 mode op1 op2 cbit)) + () + ) +) +(arithmetic3 addcr addc addc OP1_1 OP2_0 dr sr HI) +(arithmetic3 subcr subc subc OP1_3 OP2_0 dr sr HI) +(arithmetic3 addbcr addcb addc OP1_1 OP2_1 drb srb QI) +(arithmetic3 subbcr subcb subc OP1_3 OP2_1 drb srb QI) + + +;add/sub register and indirect memory +(define-pmacro (arithmetic4 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",[$"op2"]") + (+ opc1 opc2 op1 (f-op-bit2 2) op2) + (set mode op1 (insn1 mode op1 (mem HI op2) cbit)) + () + ) +) +(arithmetic4 addcr2 addc addc OP1_1 OP2_8 dr sr2 HI) +(arithmetic4 subcr2 subc subc OP1_3 OP2_8 dr sr2 HI) +(arithmetic4 addbcr2 addcb addc OP1_1 OP2_9 drb sr2 QI) +(arithmetic4 subbcr2 subcb subc OP1_3 OP2_9 drb sr2 QI) + +;add/sub register and indirect memory post increment +(define-pmacro (arithmetic5 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",[$"op2"+]") + (+ opc1 opc2 op1 (f-op-bit2 3) op2) + (sequence () + (set mode op1 (insn1 mode op1 (mem HI op2) cbit)) + (set HI op2 (add HI op2 (const 2))) + ) + () + ) +) +(arithmetic5 addcr2i addc addc OP1_1 OP2_8 dr sr2 HI) +(arithmetic5 subcr2i subc subc OP1_3 OP2_8 dr sr2 HI) +(arithmetic5 addbcr2i addcb addc OP1_1 OP2_9 drb sr2 QI) +(arithmetic5 subbcr2i subcb subc OP1_3 OP2_9 drb sr2 QI) + +;add/sub register and direct memory +(define-pmacro (arithmetic6 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (insn1 mode op1 op2)) + () + ) +) + +;add/sub register and direct memory +(define-pmacro (arithmetic7 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op2 op1) + (set (mem HI op1) (insn1 (mem HI op1) op2)) + () + ) +) +(arithmetic6 addrm2 add add OP1_0 OP2_2 regmem8 memgr8 HI) +(arithmetic7 addrm3 add add OP1_0 OP2_4 memgr8 regmem8 HI) +(arithmetic6 addrm add add OP1_0 OP2_2 reg8 memory HI) +(arithmetic7 addrm1 add add OP1_0 OP2_4 memory reg8 HI) +(arithmetic6 subrm3 sub sub OP1_2 OP2_2 regmem8 memgr8 HI) +(arithmetic7 subrm2 sub sub OP1_2 OP2_4 memgr8 regmem8 HI) +(arithmetic6 subrm1 sub sub OP1_2 OP2_2 reg8 memory HI) +(arithmetic7 subrm sub sub OP1_2 OP2_4 memory reg8 HI) +(arithmetic6 addbrm2 addb add OP1_0 OP2_3 regbmem8 memgr8 QI) +(arithmetic7 addbrm3 addb add OP1_0 OP2_5 memgr8 regbmem8 QI) +(arithmetic6 addbrm addb add OP1_0 OP2_3 regb8 memory QI) +(arithmetic7 addbrm1 addb add OP1_0 OP2_5 memory regb8 QI) +(arithmetic6 subbrm3 subb sub OP1_2 OP2_3 regbmem8 memgr8 QI) +(arithmetic7 subbrm2 subb sub OP1_2 OP2_5 memgr8 regbmem8 QI) +(arithmetic6 subbrm1 subb sub OP1_2 OP2_3 regb8 memory QI) +(arithmetic7 subbrm subb sub OP1_2 OP2_5 memory regb8 QI) + +;add/sub registers with carry +(define-pmacro (arithmetic8 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (insn1 mode op1 op2 cbit)) + () + ) +) + +;add/sub registers with carry +(define-pmacro (arithmetic9 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op2 op1) + (set (mem HI op1) (insn1 (mem HI op1) op2 cbit)) + () + ) +) +(arithmetic8 addcrm2 addc addc OP1_1 OP2_2 regmem8 memgr8 HI) +(arithmetic9 addcrm3 addc addc OP1_1 OP2_4 memgr8 regmem8 HI) +(arithmetic8 addcrm addc addc OP1_1 OP2_2 reg8 memory HI) +(arithmetic9 addcrm1 addc addc OP1_1 OP2_4 memory reg8 HI) +(arithmetic8 subcrm3 subc subc OP1_3 OP2_2 regmem8 memgr8 HI) +(arithmetic9 subcrm2 subc subc OP1_3 OP2_4 memgr8 regmem8 HI) +(arithmetic8 subcrm1 subc subc OP1_3 OP2_2 reg8 memory HI) +(arithmetic9 subcrm subc subc OP1_3 OP2_4 memory reg8 HI) +(arithmetic8 addcbrm2 addcb addc OP1_1 OP2_3 regbmem8 memgr8 QI) +(arithmetic9 addcbrm3 addcb addc OP1_1 OP2_5 memgr8 regbmem8 QI) +(arithmetic8 addcbrm addcb addc OP1_1 OP2_3 regb8 memory QI) +(arithmetic9 addcbrm1 addcb addc OP1_1 OP2_5 memory regb8 QI) +(arithmetic8 subcbrm3 subcb subc OP1_3 OP2_3 regbmem8 memgr8 QI) +(arithmetic9 subcbrm2 subcb subc OP1_3 OP2_5 memgr8 regbmem8 QI) +(arithmetic8 subcbrm1 subcb subc OP1_3 OP2_3 regb8 memory QI) +(arithmetic9 subcbrm subcb subc OP1_3 OP2_5 memory regb8 QI) + +; MUL Rwn,Rwm +(dni muls "signed multiplication" + ((PIPE OS) (IDOC ALU)) + "mul $src1,$src2" + (+ OP1_0 OP2_11 src1 src2) + (nop) ;; FIXME: (reg SI h-md 0) + () +) +; MULU Rwn,Rwm +(dni mulu "unsigned multiplication" + ((PIPE OS) (IDOC ALU)) + "mulu $src1,$src2" + (+ OP1_1 OP2_11 src1 src2) + (nop) ;; FIXME: (reg SI h-md 0) + () +) +; DIV Rwn +(dni div "16-by-16 signed division" + ((PIPE OS) (IDOC ALU)) + "div $srdiv" + (+ OP1_4 OP2_11 srdiv ) + (sequence () + (set HI (reg HI h-cr 6) (div HI (reg HI h-cr 6) srdiv)) + (set HI (reg HI h-cr 7) (mod HI (reg HI h-cr 6) srdiv)) + ) + () +) +; DIVL Rwn +(dni divl "32-by16 signed division" + ((PIPE OS) (IDOC ALU)) + "divl $srdiv" + (+ OP1_6 OP2_11 srdiv ) + (sequence () + (set HI (reg HI h-cr 6) 0) ;; FIXME: (div SI (reg SI h-md 0) srdiv)) + (set HI (reg HI h-cr 7) 0) ;; FIXME: (mod SI (reg SI h-md 0) srdiv)) + ) + () +) +; DIVLU Rwn +(dni divlu "32-by16 unsigned division" + ((PIPE OS) (IDOC ALU)) + "divlu $srdiv" + (+ OP1_7 OP2_11 srdiv ) + (sequence () + (set HI (reg HI h-cr 6) 0) ;; FIXME: (udiv SI (reg SI h-md 0) srdiv)) + (set HI (reg HI h-cr 7) 0) ;; FIXME: (umod SI (reg SI h-md 0) srdiv)) + ) + () +) +; DIVU Rwn +(dni divu "16-by-16 unsigned division" + ((PIPE OS) (IDOC ALU)) + "divu $srdiv" + (+ OP1_5 OP2_11 srdiv ) + (sequence () + (set HI (reg HI h-cr 6) (udiv HI (reg HI h-cr 6) srdiv)) + (set HI (reg HI h-cr 7) (umod HI (reg HI h-cr 6) srdiv)) + ) + () +) + +;Integer one's complement +; CPL Rwn +(dni cpl "Integer Ones complement" + ((PIPE OS) (IDOC MISC)) + "cpl $dr" + (+ OP1_9 OP2_1 dr (f-op-bit4 0)) + (set dr (inv HI dr)) + () +) + +;Bytes one's complement +; CPLB Rbn +(dni cplb "Byte Ones complement" + ((PIPE OS) (IDOC MISC)) + "cplb $drb" + (+ OP1_11 OP2_1 drb (f-op-bit4 0)) + (set drb (inv QI drb)) + () +) +;Integer two's complement +; NEG Rwn +(dni neg "Integer two's complement" + ((PIPE OS) (IDOC MISC)) + "neg $dr" + (+ OP1_8 OP2_1 dr (f-op-bit4 0)) + (set dr (neg HI dr)) + () +) +;Bytes two's complement +; NEGB Rbn +(dni negb "byte twos complement" + ((PIPE OS) (IDOC MISC)) + "negb $drb" + (+ OP1_10 OP2_1 drb (f-op-bit4 0)) + (set drb (neg QI drb)) + () +) + +;**************************************************************** +;logical insn +;**************************************************************** +;and/or/xor registers +(define-pmacro (logical name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "logical" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (insn1 mode op1 op2)) + () + ) +) + +(logical andr and and OP1_6 OP2_0 dr sr HI) +(logical orr or or OP1_7 OP2_0 dr sr HI) +(logical xorr xor xor OP1_5 OP2_0 dr sr HI) +(logical andbr andb and OP1_6 OP2_1 drb srb QI) +(logical orbr orb or OP1_7 OP2_1 drb srb QI) +(logical xorbr xorb xor OP1_5 OP2_1 drb srb QI) + +;and/or/xor register and immediate +(define-pmacro (logical1 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "logical" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"op2) + (+ opc1 opc2 op1 (f-op-bit1 0) op2) + (set mode op1 (insn1 mode op1 op2)) + () + ) +) +(logical1 andri and and OP1_6 OP2_8 dr uimm3 HI) +(logical1 orri or or OP1_7 OP2_8 dr uimm3 HI) +(logical1 xorri xor xor OP1_5 OP2_8 dr uimm3 HI) +(logical1 andbri andb and OP1_6 OP2_9 drb uimm3 QI) +(logical1 orbri orb or OP1_7 OP2_9 drb uimm3 QI) +(logical1 xorbri xorb xor OP1_5 OP2_9 drb uimm3 QI) + +;and/or/xor register and immediate +(define-pmacro (logical2 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "logical" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (insn1 mode op1 op2)) + () + ) +) +(logical2 andrim and and OP1_6 OP2_6 reg8 uimm16 HI) +(logical2 orrim or or OP1_7 OP2_6 reg8 uimm16 HI) +(logical2 xorrim xor xor OP1_5 OP2_6 reg8 uimm16 HI) + +;and/or/xor register and immediate +(define-pmacro (logical3 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "logical" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"op2) + (+ opc1 opc2 op1 op2 (f-op-bit8 0)) + (set mode op1 (insn1 mode op1 op2)) + () + ) +) +(logical3 andbrim andb and OP1_6 OP2_7 regb8 uimm8 QI) +(logical3 orbrim orb or OP1_7 OP2_7 regb8 uimm8 QI) +(logical3 xorbrim xorb xor OP1_5 OP2_7 regb8 uimm8 QI) + +;and/or/xor register and indirect memory +(define-pmacro (logical4 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "logical" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",[$"op2"]") + (+ opc1 opc2 op1 (f-op-bit2 2) op2) + (set mode op1 (insn1 mode op1 (mem HI op2))) + () + ) +) +(logical4 and2 and and OP1_6 OP2_8 dr sr2 HI) +(logical4 or2 or or OP1_7 OP2_8 dr sr2 HI) +(logical4 xor2 xor xor OP1_5 OP2_8 dr sr2 HI) +(logical4 andb2 andb and OP1_6 OP2_9 drb sr2 QI) +(logical4 orb2 orb or OP1_7 OP2_9 drb sr2 QI) +(logical4 xorb2 xorb xor OP1_5 OP2_9 drb sr2 QI) + +;and/or/xor register and indirect memory post increment +(define-pmacro (logical5 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "logical" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",[$"op2"+]") + (+ opc1 opc2 op1 (f-op-bit2 3) op2) + (sequence () + (set mode op1 (insn1 mode op1 (mem HI op2))) + (set HI op2 (add HI op2 (const 2))) + ) + () + ) +) +(logical5 and2i and and OP1_6 OP2_8 dr sr2 HI) +(logical5 or2i or or OP1_7 OP2_8 dr sr2 HI) +(logical5 xor2i xor xor OP1_5 OP2_8 dr sr2 HI) +(logical5 andb2i andb and OP1_6 OP2_9 drb sr2 QI) +(logical5 orb2i orb or OP1_7 OP2_9 drb sr2 QI) +(logical5 xorb2i xorb xor OP1_5 OP2_9 drb sr2 QI) + +;add/sub register and immediate +(define-pmacro (logical7 name insn insn1 opc1 opc2 op1 op2 mode dir) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"dir"$"op1 ",$"op2) + (+ opc1 opc2 op1 op2) + (set (mem HI op1) (insn1 (mem HI op1) op2 )) + () + ) +) +(logical7 andpofr and and OP1_6 OP2_2 reg8 upof16 HI "pof") +(logical7 orpofr or or OP1_7 OP2_2 reg8 upof16 HI "pof") +(logical7 xorpofr xor xor OP1_5 OP2_2 reg8 upof16 HI "pof") +(logical7 andbpofr andb and OP1_6 OP2_3 regb8 upof16 QI "pof") +(logical7 orbpofr orb or OP1_7 OP2_3 regb8 upof16 QI "pof") +(logical7 xorbpofr xorb xor OP1_5 OP2_3 regb8 upof16 QI "pof") + +;add/sub register and immediate +(define-pmacro (logical8 name insn insn1 opc1 opc2 op1 op2 mode dir) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"dir"$"op1 ",$"op2) + (+ opc1 opc2 op1 op2) + (set (mem HI op1) (insn1 (mem HI op1) op2 )) + () + ) +) +(logical8 andrpofr and and OP1_6 OP2_4 upof16 reg8 HI "pof") +(logical8 orrpofr or or OP1_7 OP2_4 upof16 reg8 HI "pof") +(logical8 xorrpofr xor xor OP1_5 OP2_4 upof16 reg8 HI "pof") +(logical8 andbrpofr andb and OP1_6 OP2_5 upof16 regb8 QI "pof") +(logical8 orbrpofr orb or OP1_7 OP2_5 upof16 regb8 QI "pof") +(logical8 xorbrpofr xorb xor OP1_5 OP2_5 upof16 regb8 QI "pof") + +;and/or/xor register and direct memory +(define-pmacro (logical6 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (insn1 mode op1 op2)) + () + ) +) + +;and/or/xor register and direct memory +(define-pmacro (logical7 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "arithmetic" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op2 op1) + (set (mem HI op1) (insn1 (mem HI op1) op2)) + () + ) +) +(logical6 andrm2 and and OP1_6 OP2_2 regmem8 memgr8 HI) +(logical7 andrm3 and and OP1_6 OP2_4 memgr8 regmem8 HI) +(logical6 andrm and and OP1_6 OP2_2 reg8 memory HI) +(logical7 andrm1 and and OP1_6 OP2_4 memory reg8 HI) +(logical6 orrm3 or or OP1_7 OP2_2 regmem8 memgr8 HI) +(logical7 orrm2 or or OP1_7 OP2_4 memgr8 regmem8 HI) +(logical6 orrm1 or or OP1_7 OP2_2 reg8 memory HI) +(logical7 orrm or or OP1_7 OP2_4 memory reg8 HI) +(logical6 xorrm3 xor xor OP1_5 OP2_2 regmem8 memgr8 HI) +(logical7 xorrm2 xor xor OP1_5 OP2_4 memgr8 regmem8 HI) +(logical6 xorrm1 xor xor OP1_5 OP2_2 reg8 memory HI) +(logical7 xorrm xor xor OP1_5 OP2_4 memory reg8 HI) +(logical6 andbrm2 andb and OP1_6 OP2_3 regbmem8 memgr8 QI) +(logical7 andbrm3 andb and OP1_6 OP2_5 memgr8 regbmem8 QI) +(logical6 andbrm andb and OP1_6 OP2_3 regb8 memory QI) +(logical7 andbrm1 andb and OP1_6 OP2_5 memory regb8 QI) +(logical6 orbrm3 orb or OP1_7 OP2_3 regbmem8 memgr8 QI) +(logical7 orbrm2 orb or OP1_7 OP2_5 memgr8 regbmem8 QI) +(logical6 orbrm1 orb or OP1_7 OP2_3 regb8 memory QI) +(logical7 orbrm orb or OP1_7 OP2_5 memory regb8 QI) +(logical6 xorbrm3 xorb xor OP1_5 OP2_3 regbmem8 memgr8 QI) +(logical7 xorbrm2 xorb xor OP1_5 OP2_5 memgr8 regbmem8 QI) +(logical6 xorbrm1 xorb xor OP1_5 OP2_3 regb8 memory QI) +(logical7 xorbrm xorb xor OP1_5 OP2_5 memory regb8 QI) + +;**************************************************************** +;logical insn +;**************************************************************** +;mov registers +(define-pmacro (move name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "mov registers" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 op2) + () + ) +) +(move movr mov OP1_15 OP2_0 dr sr HI) +(move movrb movb OP1_15 OP2_1 drb srb HI) + +;mov register and immediate +(define-pmacro (move1 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"op1 ",$hash$"op2) + (+ opc1 opc2 op2 op1) + (set mode op1 op2) + () + ) +) +(move1 movri mov OP1_14 OP2_0 dri u4 HI) +(move1 movbri movb OP1_14 OP2_1 srb u4 QI) + +; MOV Rwn,#data16 +(dni movi "move immediate to register" + ((PIPE OS) (IDOC MOVE)) + "mov $reg8,$hash$uimm16" + (+ OP1_14 OP2_6 reg8 uimm16) + (set HI reg8 uimm16) + () +) + +; MOVB reg,#data8 +(dni movbi "move immediate to register" + ((PIPE OS) (IDOC MOVE)) + "movb $regb8,$hash$uimm8" + (+ OP1_14 OP2_7 regb8 uimm8 (f-op-bit8 0)) + (set QI regb8 uimm8) + () +) + +;move and indirect memory +(define-pmacro (mov2 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"op1 ",[$"op2"]") + (+ opc1 opc2 op1 op2) + (set mode op1 (mem HI op2)) + () + ) +) +(mov2 movr2 mov OP1_10 OP2_8 dr sr HI) +(mov2 movbr2 movb OP1_10 OP2_9 drb sr QI) + +;move and indirect memory +(define-pmacro (mov3 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " [$"op2 "],$"op1) + (+ opc1 opc2 op1 op2) + (set mode op1 (mem HI op2)) + () + ) +) +(mov3 movri2 mov OP1_11 OP2_8 dr sr HI) +(mov3 movbri2 movb OP1_11 OP2_9 drb sr QI) + +;move and indirect memory +(define-pmacro (mov4 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " [-$"op2 "],$"op1) + (+ opc1 opc2 op1 op2) + (sequence HI () + (set op1 (sub op2 (const HI 2))) + (set HI (mem HI op2) op1) + ) + () + ) +) +(mov4 movri3 mov OP1_8 OP2_8 dr sr HI) +(mov4 movbri3 movb OP1_8 OP2_9 drb sr QI) + +;mov register and indirect memory post increment +(define-pmacro (mov5 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"op1 ",[$"op2"+]") + (+ opc1 opc2 op1 op2) + (sequence () + (set mode op1 (mem HI op2)) + (set HI op2 (add HI op2 (const 2))) + ) + () + ) +) +(mov5 mov2i mov OP1_9 OP2_8 dr sr HI) +(mov5 movb2i movb OP1_9 OP2_9 drb sr HI) + +;mov indirect memory +(define-pmacro (mov6 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " [$"op1 "],[$"op2"]") + (+ opc1 opc2 op1 op2) + (set HI (mem HI op1) (mem HI op2)) + () + ) +) +(mov6 mov6i mov OP1_12 OP2_8 dr sr HI) +(mov6 movb6i movb OP1_12 OP2_9 dr sr HI) + +;mov indirect memory +(define-pmacro (mov7 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " [$"op1 "+],[$"op2"]") + (+ opc1 opc2 op1 op2) + (sequence () + (set mode (mem mode op1) (mem mode op2)) + (set mode op1 (add mode op1 (const mode 2))) + ) + () + ) +) +(mov7 mov7i mov OP1_13 OP2_8 dr sr HI) +(mov7 movb7i movb OP1_13 OP2_9 dr sr HI) + +;mov indirect memory +(define-pmacro (mov8 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " [$"op1 "],[$"op2"+]") + (+ opc1 opc2 op1 op2) + (sequence () + (set mode (mem mode op1) (mem mode op2)) + (set mode op2 (add mode op2 (const mode 2))) + ) + () + ) +) +(mov8 mov8i mov OP1_14 OP2_8 dr sr HI) +(mov8 movb8i movb OP1_14 OP2_9 dr sr HI) + +;mov indirect memory +(define-pmacro (mov9 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"op1 ",[$"op2"+$hash$"uimm16"]") + (+ opc1 opc2 op1 op2 uimm16) + (sequence mode ((mode tmp1)) + (set mode tmp1 (add HI op2 uimm16)) + (set mode op1 (mem HI tmp1)) + ) + () + ) +) +(mov9 mov9i mov OP1_13 OP2_4 dr sr HI) +(mov9 movb9i movb OP1_15 OP2_4 drb sr QI) + +;mov indirect memory +(define-pmacro (mov10 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " [$"op2"+$hash$"uimm16 "],$"op1) + (+ opc1 opc2 op1 op2 uimm16) + (sequence mode ((mode tmp1)) + (set mode tmp1 (add HI op1 uimm16)) + (set mode (mem HI tmp1) op1) + ) + () + ) +) +(mov10 mov10i mov OP1_12 OP2_4 dr sr HI) +(mov10 movb10i movb OP1_14 OP2_4 drb sr QI) + +;move and indirect memory +(define-pmacro (mov11 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " [$"op1 "],$"op2) + (+ opc1 opc2 (f-op-lbit4 0) op1 op2) + (set (mem mode op1) (mem HI op2)) + () + ) +) +(mov11 movri11 mov OP1_8 OP2_4 src2 memory HI) +(mov11 movbri11 movb OP1_10 OP2_4 src2 memory HI) + +;move and indirect memory +(define-pmacro (mov12 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"op2 ",[$"op1"]") + (+ opc1 opc2 (f-op-lbit4 0) op1 op2) + (set (mem HI op2) (mem mode op1)) + () + ) +) +(mov12 movri12 mov OP1_9 OP2_4 src2 memory HI) +(mov12 movbri12 movb OP1_11 OP2_4 src2 memory HI) + +(define-pmacro (movemem3 name insn opc1 opc2 op1 op2 dir) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"op1 ",$hash$"dir"$"op2) + (+ opc1 opc2 op1 op2) + (set HI op1 op2) + () + ) +) +(movemem3 movehm5 mov OP1_14 OP2_6 regoff8 upof16 "pof") +(movemem3 movehm6 mov OP1_14 OP2_6 regoff8 upag16 "pag") +(movemem3 movehm7 mov OP1_14 OP2_6 regoff8 useg16 "segm") +(movemem3 movehm8 mov OP1_14 OP2_6 regoff8 usof16 "sof") + +(define-pmacro (movemem4 name insn opc1 opc2 op1 op2 dir) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"op1 ",$hash$"dir"$"op2) + (+ opc1 opc2 op1 op2 (f-op-bit8 0)) + (set QI op1 op2) + () + ) +) +(movemem4 movehm9 movb OP1_14 OP2_7 regb8 uimm8 "pof") +(movemem4 movehm10 movb OP1_14 OP2_7 regoff8 uimm8 "pag") + +(define-pmacro (movemem name insn opc1 opc2 op1 op2 mode dir) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"op1 ",$"dir"$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (mem HI op2)) + () + ) +) +(movemem movrmp mov OP1_15 OP2_2 regoff8 upof16 HI "pof") +(movemem movrmp1 movb OP1_15 OP2_3 regb8 upof16 QI "pof") +(movemem movrmp2 mov OP1_15 OP2_2 regoff8 upag16 HI "pag") +(movemem movrmp3 movb OP1_15 OP2_3 regb8 upag16 QI "pag") + +(define-pmacro (movemem1 name insn opc1 opc2 op1 op2 dir) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"dir"$"op1 ",$"op2) + (+ opc1 opc2 op2 op1) + (set (mem HI op1) op2 ) + () + ) +) +(movemem1 movrmp4 mov OP1_15 OP2_6 upof16 regoff8 "pof") +(movemem1 movrmp5 movb OP1_15 OP2_7 upof16 regb8 "pof") + +(define-pmacro (movemem2 name insn opc1 opc2 op1 op2 mode dir) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"op1 ",$hash$"dir"$"op2) + (+ opc1 opc2 op2 op1) + (set mode op1 op2) + () + ) +) +(movemem2 movehm1 mov OP1_14 OP2_0 dri u4 HI "pof") +(movemem2 movehm2 movb OP1_14 OP2_1 srb u4 QI "pof") +(movemem2 movehm3 mov OP1_14 OP2_0 dri u4 HI "pag") +(movemem2 movehm4 movb OP1_14 OP2_1 srb u4 QI "pag") + +;move register and direct memory +(define-pmacro (move12 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (mem HI op2)) + () + ) +) + +;move register and direct memory +(define-pmacro (move13 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op2 op1) + (set (mem HI op1) op2) + () + ) +) +(move12 mve12 mov OP1_15 OP2_2 regmem8 memgr8 HI) +(move13 mve13 mov OP1_15 OP2_6 memgr8 regmem8 HI) +(move12 mover12 mov OP1_15 OP2_2 reg8 memory HI) +(move13 mvr13 mov OP1_15 OP2_6 memory reg8 HI) +(move12 mver12 movb OP1_15 OP2_3 regbmem8 memgr8 QI) +(move13 mver13 movb OP1_15 OP2_7 memgr8 regbmem8 QI) +(move12 movr12 movb OP1_15 OP2_3 regb8 memory QI) +(move13 movr13 movb OP1_15 OP2_7 memory regb8 QI) + +; MOVBS Rw,Rb +(dni movbsrr "mov byte register with sign extension to word register" + ((PIPE OS) (IDOC MOVE)) + "movbs $sr,$drb" + (+ OP1_13 OP2_0 drb sr) + (sequence () + (if QI (and QI drb (const 128)) + (set HI sr (or HI (const HI 65280) drb))) + (set HI sr (and HI (const HI 255) drb)) + ) + () +) + +; MOVBZ Rw,Rb +(dni movbzrr "mov byte register with zero extension to word register" + ((PIPE OS) (IDOC MOVE)) + "movbz $sr,$drb" + (+ OP1_12 OP2_0 drb sr) + (set HI sr (and HI (const HI 255) drb)) + () +) + +; MOVBS reg,POF mem +(dni movbsrpofm "mov memory to byte register" + ((PIPE OS) (IDOC MOVE)) + "movbs $regmem8,$pof$upof16" + (+ OP1_13 OP2_2 regmem8 upof16) + (set QI regmem8 (mem HI upof16)) + () +) + +; MOVBS pof,reg +(dni movbspofmr "mov memory to byte register" + ((PIPE OS) (IDOC MOVE)) + "movbs $pof$upof16,$regbmem8" + (+ OP1_13 OP2_5 upof16 regbmem8 ) + (set QI (mem HI upof16) regbmem8) + () +) + +; MOVBZ reg,POF mem +(dni movbzrpofm "mov memory to byte register" + ((PIPE OS) (IDOC MOVE)) + "movbz $reg8,$pof$upof16" + (+ OP1_12 OP2_2 reg8 upof16) + (set QI reg8 (mem HI upof16)) + () +) + +; MOVBZ pof,reg +(dni movbzpofmr "mov memory to byte register" + ((PIPE OS) (IDOC MOVE)) + "movbz $pof$upof16,$regb8" + (+ OP1_12 OP2_5 upof16 regb8 ) + (set QI (mem HI upof16) regb8) + () +) + +;move register and direct memory +(define-pmacro (move14 name insn opc1 opc2 op1 op2 ) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op1 op2) + (set HI op1 (and HI (const HI 255) (mem QI op2))) + () + ) +) + +;move register and direct memory +(define-pmacro (move15 name insn opc1 opc2 op1 op2 ) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op2 op1) + (set HI (mem HI op1) (and HI (const HI 255) op2)) + () + ) +) +(move14 movebs14 movbs OP1_13 OP2_2 regmem8 memgr8 ) +(move15 movebs15 movbs OP1_13 OP2_5 memgr8 regbmem8 ) +(move14 moverbs14 movbs OP1_13 OP2_2 reg8 memory ) +(move15 movrbs15 movbs OP1_13 OP2_5 memory regb8 ) +(move14 movebz14 movbz OP1_12 OP2_2 regmem8 memgr8 ) +(move15 movebz15 movbz OP1_12 OP2_5 memgr8 regbmem8 ) +(move14 moverbz14 movbz OP1_12 OP2_2 reg8 memory ) +(move15 movrbz15 movbz OP1_12 OP2_5 memory regb8 ) + + +;mov registers +(define-pmacro (moveb1 name insn opc1 opc2 op1 op2) + (dni name + (.str name "move" ) + ((PIPE OS) (IDOC MOVE)) + (.str insn " $"op2 ",$"op1) + (+ opc1 opc2 op1 op2) + (sequence () + (if QI (and QI op1 (const 128)) + (set HI op2 (or HI (const HI 65280) op1))) + (set HI op2 (and HI (const HI 255) op1)) + ) + () + ) +) +(moveb1 movrbs movbs OP1_13 OP2_0 drb sr ) +(moveb1 movrbz movbz OP1_12 OP2_0 drb sr ) + + + +;jump and call insns +;****************************************************************** +;Absolute conditional jump +(define-pmacro (jmpabs name insn) + (dni name + (.str name "Absolute conditional jump" ) + ((PIPE OS) (IDOC JMP)) + (.str insn " $extcond,$caddr") + (+ OP1_14 OP2_10 extcond (f-op-bitone 0) bitone bit01 caddr) + (sequence ((HI tmp1) (HI tmp2)) + (set tmp1 (mem HI caddr)) + (set tmp2 (sub HI pc (mem HI caddr))) + (if (gt tmp2 (const 0)) ;; FIXME: (lt tmp2 (const 32)) (eq tmp2 (const 32)) + (set bitone (const 1))) + (if (lt tmp2 (const 0)) ;; FIXME: (eq tmp2 (const 0)) (gt tmp2 (const 32)) + (set bitone (const 0))) + (if (eq extcond (const 1)) ;; FIXME: (ne extcond cc_Z)) + (set bit01 (const 0)) + (set HI pc (mem HI caddr))) + (if (ne extcond (const 1)) ;; FIXME: (eq extcond cc_Z)) + (set bit01 (const 1)) + (set HI pc (add HI pc (const 2)))) + ) + () + ) +) + +(jmpabs jmpa0 jmpa+) +(jmpabs jmpa1 jmpa) + +; JMPA- cc,caddr +(dni jmpa- "Absolute conditional jump" + (COND-CTI (PIPE OS) (IDOC JMP)) + "jmpa- $extcond,$caddr" + (+ OP1_14 OP2_10 extcond (f-op-bitone 0) bitone (f-op-1bit 1) caddr) + (sequence ((HI tmp1) (HI tmp2)) + (set tmp1 (mem HI caddr)) + (set tmp2 (sub HI pc (mem HI caddr))) + (if (gt tmp2 (const 0)) ;; FIXME: (lt tmp2 (const 32)) (eq tmp2 (const 32)) + (set bitone (const 1))) + (if (lt tmp2 (const 0)) ;; FIXME: (eq tmp2 (const 0)) (gt tmp2 (const 32)) + (set bitone (const 0))) + (set HI pc (add HI pc (const 2))) + ) + () +) + +; JMPI cc,[Rwn] +(dni jmpi "Indirect conditional jump" + (COND-CTI (PIPE OS) (IDOC JMP)) + "jmpi $icond,[$sr]" + (+ OP1_9 OP2_12 icond sr) + (sequence () + (if (eq icond (const 1)) + (set HI pc (mem HI sr))) + (set HI pc (add HI pc (const 2))) + ) + () +) + +(define-pmacro (jmprel name insn opc1) + (dni name + (.str name "conditional" ) + (COND-CTI (PIPE OS) (IDOC JMP)) + (.str insn " $cond,$rel") + (+ opc1 OP2_13 rel) + (sequence () + (if (eq cond (const 1)) + (sequence () + (if QI (lt QI rel (const 0)) + (sequence () + ;; FIXME: (neg QI rel) + ;; FIXME: (add QI rel (const 1)) + ;; FIXME: (mul QI rel (const 2)) + (set HI pc (sub HI pc rel)) + )) + (set HI pc (add HI pc (mul QI rel (const 2)))) + ) + ) + (set HI pc pc) + ) + () + ) +) + +(jmprel jmpr_nenz jmpr COND_NE_NZ ) +(jmprel jmpr_sgt jmpr COND_SGT ) +(jmprel jmpr_z jmpr COND_Z ) +(jmprel jmpr_v jmpr COND_V ) +(jmprel jmpr_nv jmpr COND_NV ) +(jmprel jmpr_n jmpr COND_N ) +(jmprel jmpr_nn jmpr COND_NN ) +(jmprel jmpr_c jmpr COND_C ) +(jmprel jmpr_nc jmpr COND_NC ) +(jmprel jmpr_eq jmpr COND_EQ ) +(jmprel jmpr_ne jmpr COND_NE ) +(jmprel jmpr_ult jmpr COND_ULT ) +(jmprel jmpr_ule jmpr COND_ULE ) +(jmprel jmpr_uge jmpr COND_UGE ) +(jmprel jmpr_ugt jmpr COND_UGT ) +(jmprel jmpr_sle jmpr COND_SLE ) +(jmprel jmpr_sge jmpr COND_SGE ) +(jmprel jmpr_net jmpr COND_NET ) +(jmprel jmpr_uc jmpr COND_UC ) +(jmprel jmpr_slt jmpr COND_SLT ) + + + + +; JMPS seg,caddr +(dni jmpseg "absolute inter-segment jump" + (UNCOND-CTI(PIPE OS) (IDOC JMP)) + "jmps $hash$segm$useg8,$hash$sof$usof16" + (+ OP1_15 OP2_10 seg usof16) + (sequence () + (if QI (eq BI sgtdisbit (const BI 0)) + (set QI (reg h-cr 10) useg8)) + (nop) + (set HI pc usof16) + ) + () +) + +; JMPS seg,caddr +(dni jmps "absolute inter-segment jump" + (UNCOND-CTI(PIPE OS) (IDOC JMP)) + "jmps $seg,$caddr" + (+ OP1_15 OP2_10 seg caddr) + (sequence () + (if QI (eq BI sgtdisbit (const BI 0)) + (set QI (reg h-cr 10) seg)) + (nop) + (set HI pc caddr) + ) + () +) + + +;relative jump if bit set +;JB bitaddrQ.q,rel +(dni jb "relative jump if bit set" + ((PIPE OS) (IDOC JMP)) + "jb $genreg$dot$qlobit,$relhi" + (+ OP1_8 OP2_10 genreg relhi qlobit (f-qhibit 0)) + (sequence ((HI tmp1) (HI tmp2)) + (set HI tmp1 genreg) + (set HI tmp2 (const 1)) + (sll HI tmp2 qlobit) + (set HI tmp2 (and tmp1 tmp2)) + (if (eq tmp2 (const 1)) + (sequence () + (if QI (lt QI relhi (const 0)) + (set HI pc (add HI pc (mul QI relhi (const 2))))) + )) + (set HI pc (add HI pc (const 4))) + ) + () +) + +;relative jump if bit set and clear bit +;JBC bitaddrQ.q,rel +(dni jbc "relative jump if bit set and clear bit" + ((PIPE OS) (IDOC JMP)) + "jbc $genreg$dot$qlobit,$relhi" + (+ OP1_10 OP2_10 genreg relhi qlobit (f-qhibit 0)) + (sequence ((HI tmp1) (HI tmp2)) + (set HI tmp1 genreg) + (set HI tmp2 (const 1)) + (sll HI tmp2 qlobit) + (set HI tmp2 (and tmp1 tmp2)) + (if (eq tmp2 (const 1)) + (sequence () + (if QI (lt QI relhi (const 0)) + (set tmp2 (const 1)) + (set tmp1 genreg) + ;; FIXME: (sll tmp2 qlobit) + ;; FIXME: (inv tmp2) + (set HI tmp1(and tmp1 tmp2)) + (set HI genreg tmp1) + (set HI pc (add HI pc (mul QI relhi (const 2))))) + )) + (set HI pc (add HI pc (const 4))) + ) + () +) + +;relative jump if bit set +;JNB bitaddrQ.q,rel +(dni jnb "relative jump if bit not set" + ((PIPE OS) (IDOC JMP)) + "jnb $genreg$dot$qlobit,$relhi" + (+ OP1_9 OP2_10 genreg relhi qlobit (f-qhibit 0)) + (sequence ((HI tmp1) (HI tmp2)) + (set HI tmp1 genreg) + (set HI tmp2 (const 1)) + (sll HI tmp2 qlobit) + (set HI tmp2 (and tmp1 tmp2)) + (if (eq tmp2 (const 0)) + (sequence () + (if QI (lt QI relhi (const 0)) + (set HI pc (add HI pc (mul QI relhi (const 2))))) + )) + (set HI pc (add HI pc (const 4))) + ) + () +) + +;relative jump if bit not set and set bit +;JNBS bitaddrQ.q,rel +(dni jnbs "relative jump if bit not set and set bit" + ((PIPE OS) (IDOC JMP)) + "jnbs $genreg$dot$qlobit,$relhi" + (+ OP1_11 OP2_10 genreg relhi qlobit (f-qhibit 0)) + (sequence ((HI tmp1) (HI tmp2)) + (set HI tmp1 genreg) + (set HI tmp2 (const 1)) + (sll HI tmp2 qlobit) + (set HI tmp2 (and tmp1 tmp2)) + (if (eq tmp2 (const 0)) + (sequence () + (if QI (lt QI relhi (const 0)) + (set tmp2 (const 1)) + (set tmp1 reg8) + ;; FIXME: (sll tmp2 qbit) + (set BI tmp1(or tmp1 tmp2)) + (set HI reg8 tmp1) + (set HI pc (add HI pc (mul QI relhi (const 2))))) + )) + (set HI pc (add HI pc (const 4))) + ) + () +) + + +;Absolute conditional call +(define-pmacro (callabs name insn) + (dni name + (.str name "Absolute conditional call" ) + ((PIPE OS) (IDOC JMP)) + (.str insn " $extcond,$caddr") + (+ OP1_12 OP2_10 extcond (f-op-2bit 0) bit01 caddr) + (sequence () + (if (eq extcond (const 1)) + (set bit01 (const 0)) + (set (reg h-cr 9) (sub HI (reg h-cr 9) (const 2))) + (set HI (mem HI (reg h-cr 9)) pc) + (set HI pc (mem HI caddr))) + (if (ne extcond (const 1)) + (set bit01 (const 1)) + (set HI pc (add HI pc (const 2)))) + ) + () + ) +) + +(callabs calla0 calla+) +(callabs calla1 calla) + +; CALLA- cc,caddr +(dni calla- "Absolute conditional call" + (COND-CTI (PIPE OS) (IDOC JMP)) + "calla- $extcond,$caddr" + (+ OP1_12 OP2_10 extcond (f-op-bit3 1) caddr) + (sequence () + (if (eq extcond (const 1)) + (set (reg h-cr 9) (sub HI (reg h-cr 9) (const 2))) + (set HI (mem HI (reg h-cr 9)) pc) + (set HI pc (mem HI caddr))) + (set HI pc (add HI pc (const 2))) + ) + () +) + +; CALLI cc,[Rwn] +(dni calli "indirect subroutine call" + (COND-CTI (PIPE OS) (IDOC JMP)) + "calli $icond,[$sr]" + (+ OP1_10 OP2_11 icond sr) + (sequence () + (if (eq icond (const 1)) + (sequence () + (set (reg h-cr 9) (sub HI (reg h-cr 9) (const 2))) + (set HI (mem HI (reg h-cr 9)) pc) + (set HI pc (mem HI sr)) + ) + ) + (set HI pc (add HI pc (const 2))) + ) + () +) + +; CALLR rel +(dni callr "Call subroutine with PC relative signed 8 bit offset" + ( COND-CTI (PIPE OS) (IDOC JMP)) + "callr $rel" + (+ OP1_11 OP2_11 rel) + (sequence () + (set (reg h-cr 9) (sub HI (reg h-cr 9) (const 2))) + (set HI (mem HI (reg h-cr 9)) pc) + (sequence () + (if QI (lt QI rel (const 0)) + (sequence () + ;; FIXME: (neg QI rel) + ;; FIXME: (add QI rel (const 1)) + ;; FIXME: (mul QI rel (const 2)) + (set HI pc (sub HI pc rel)) + )) + (set HI pc (add HI pc (mul QI rel (const 2)))) + ) + ) + () +) + + +; CALLS seg,caddr +(dni callseg "call inter-segment subroutine" + (UNCOND-CTI (PIPE OS) (IDOC JMP)) + "calls $hash$segm$useg8,$hash$sof$usof16" + (+ OP1_13 OP2_10 useg8 usof16) + (sequence () + (set (reg h-cr 9) (sub HI (reg h-cr 9) (const 2))) + (set HI (mem HI (reg h-cr 9)) (reg h-cr 10)) + (set (reg h-cr 9) (sub HI (reg h-cr 9) (const 2))) + (set HI (mem HI (reg h-cr 9)) pc) + (if QI (eq BI sgtdisbit (const BI 0)) + (set QI (reg h-cr 10) useg8)) + (nop) + (set HI pc usof16) + ) + () +) + +; CALLS seg,caddr +(dni calls "call inter-segment subroutine" + (UNCOND-CTI (PIPE OS) (IDOC JMP)) + "calls $seg,$caddr" + (+ OP1_13 OP2_10 seg caddr) + (sequence () + (set (reg h-cr 9) (sub HI (reg h-cr 9) (const 2))) + (set HI (mem HI (reg h-cr 9)) (reg h-cr 10)) + (set (reg h-cr 9) (sub HI (reg h-cr 9) (const 2))) + (set HI (mem HI (reg h-cr 9)) pc) + (if QI (eq BI sgtdisbit (const BI 0)) + (set QI (reg h-cr 10) seg)) + (nop) + (set HI pc caddr) + ) + () +) + +; PCALL reg,caddr +(dni pcall "push word and call absolute subroutine" + (UNCOND-CTI (PIPE OS) (IDOC JMP)) + "pcall $reg8,$caddr" + (+ OP1_14 OP2_2 reg8 caddr) + (sequence ((HI tmp1)) + (set HI tmp1 reg8) + (set (reg h-cr 9) (sub HI (reg h-cr 9) (const 2))) + (set HI (mem HI (reg h-cr 9)) tmp1) + (set (reg h-cr 9) (sub HI (reg h-cr 9) (const 2))) + (set HI (mem HI (reg h-cr 9)) pc) + (set HI pc caddr) + ) + () +) + +; TRAP #uimm7 +(dni trap "software trap" + (UNCOND-CTI (PIPE OS) (IDOC JMP)) + "trap $hash$uimm7" + (+ OP1_9 OP2_11 uimm7 (f-op-1bit 0)) + (sequence () + (set (reg h-cr 9) (sub HI (reg h-cr 9) (const 2))) + (set HI (mem HI (reg h-cr 9)) (reg h-cr 4)) + (if QI (eq BI sgtdisbit (const BI 0)) + (set (reg h-cr 9) (sub HI (reg h-cr 9) (const 2))) + (set HI (mem HI (reg h-cr 9)) (reg h-cr 10) ) + ) + (nop) + (set HI (reg h-cr 10) (reg h-cr 11)) + (set (reg h-cr 9) (sub HI (reg h-cr 9) (const 2))) + (set HI (mem HI (reg h-cr 9)) pc) + (set HI pc (mul QI uimm7 (const 4))) + ) + () +) + +;Return insns +; RET +(dni ret "return from subroutine" + (UNCOND-CTI (PIPE OS) (IDOC JMP)) + "ret" + (+ OP1_12 OP2_11 (f-op-bit8 0)) + (sequence () + (set HI pc (mem HI (reg h-cr 9))) + (set (reg h-cr 9) (add HI (reg h-cr 9) (const 2))) + ) + () +) + +; RETS +(dni rets "return from inter-segment sunroutine" + (UNCOND-CTI (PIPE OS) (IDOC JMP)) + "rets" + (+ OP1_13 OP2_11 (f-op-bit8 0)) + (sequence () + (set HI pc (mem HI (reg h-cr 9))) + (set (reg h-cr 9) (add HI (reg h-cr 9) (const 2))) + (if QI (eq BI sgtdisbit (const BI 0)) + (set HI (reg h-cr 10) (mem HI (reg h-cr 9))) + ) + (nop) + (set (reg h-cr 9) (add HI (reg h-cr 9) (const 2))) + ) + () +) + +; RETP reg +(dni retp "return from subroutine and pop word register" + (UNCOND-CTI (PIPE OS) (IDOC JMP)) + "retp $reg8" + (+ OP1_14 OP2_11 reg8) + (sequence ((HI tmp1)) + (set HI pc (mem HI (reg h-cr 9))) + (set (reg h-cr 9) (add HI (reg h-cr 9) (const 2))) + (set HI tmp1 (mem HI (reg h-cr 9))) + (set (reg h-cr 9) (add HI (reg h-cr 9) (const 2))) + (set HI reg8 tmp1) + ) + () +) + +; RETI +(dni reti "return from ISR" + (UNCOND-CTI (PIPE OS) (IDOC JMP)) + "reti" + (+ OP1_15 OP2_11 (f-op-lbit4 8) (f-op-bit4 8)) + (sequence () + (set HI pc (mem HI (reg h-cr 9))) + (set (reg h-cr 9) (add HI (reg h-cr 9) (const 2))) + (if QI (eq BI sgtdisbit (const BI 0)) + (sequence () + (set HI (reg h-cr 10) (mem HI (reg h-cr 9))) + (set (reg h-cr 9) (add HI (reg h-cr 9) (const 2))) + ) + ) + (nop) + (set HI (reg h-cr 4) (mem HI (reg h-cr 9))) + (set (reg h-cr 9) (add HI (reg h-cr 9) (const 2))) + ) + () +) + +;stack operation insn +;****************************************************************** +; POP reg +(dni pop "restore register from system stack" + ((PIPE OS) (IDOC MISC)) + "pop $reg8" + (+ OP1_15 OP2_12 reg8) + (sequence ((HI tmp1)) + (set HI tmp1 (mem HI (reg h-cr 9))) + (set (reg h-cr 9) (add HI (reg h-cr 9) (const 2))) + (set HI reg8 tmp1) + ) + () +) + +; PUSH reg +(dni push "save register on system stack" + ((PIPE OS) (IDOC MISC)) + "push $reg8" + (+ OP1_14 OP2_12 reg8) + (sequence ((HI tmp1)) + (set HI tmp1 reg8) + (set (reg h-cr 9) (sub HI (reg h-cr 9) (const 2))) + (set HI (mem HI (reg h-cr 9)) tmp1) + ) + () +) + +;context switching insns +; SCXT reg,#data16 +(dni scxti "Push word register on stack and update same with immediate data" + ((PIPE OS) (IDOC MISC)) + "scxt $reg8,$hash$uimm16" + (+ OP1_12 OP2_6 reg8 uimm16) + (sequence ((HI tmp1) (HI tmp2)) + (set HI tmp1 reg8) + (set HI tmp2 uimm16) + ;; FIXME: (sub HI (reg HI h-cr 9) (const 2)) + (set HI (reg HI h-cr 9) tmp1) + (set HI reg8 tmp2) + ) + () +) + +; SCXT reg,POF mem +(dni scxtrpofm "mov memory to byte register" + ((PIPE OS) (IDOC MOVE)) + "scxt $reg8,$pof$upof16" + (+ OP1_13 OP2_6 reg8 upof16) + (set QI reg8 (mem HI upof16)) + () +) + +; SCXT regmem8,memgr8 +(dni scxtmg "Push word register on stack and update same with direct memory" + ((PIPE OS) (IDOC MISC)) + "scxt $regmem8,$memgr8" + (+ OP1_13 OP2_6 regmem8 memgr8) + (sequence ((HI tmp1) (HI tmp2)) + (set HI tmp1 regmem8) + (set HI tmp2 memgr8) + ;; FIXME: (sub HI (reg HI h-cr 9) (const 2)) + (set HI (reg HI h-cr 9) tmp1) + (set HI regmem8 tmp2) + ) + () +) + +; SCXT reg,mem +(dni scxtm "Push word register on stack and update same with direct memory" + ((PIPE OS) (IDOC MISC)) + "scxt $reg8,$memory" + (+ OP1_13 OP2_6 reg8 memory) + (sequence ((HI tmp1) (HI tmp2)) + (set HI tmp1 reg8) + (set HI tmp2 memory) + ;; FIXME: (sub HI (reg HI h-cr 9) (const 2)) + (set HI (reg HI h-cr 9) tmp1) + (set HI reg8 tmp2) + ) + () +) + +;No operation +; NOP +(dni nop "nop" + ((PIPE OS) (IDOC MISC)) + "nop" + (+ OP1_12 OP2_12 (f-op-bit8 0)) + () + () +) + +;*********system control instructions *********************/ + +(define-pmacro (sysctrl name insn opc1 opc2 op1 op2 op3) + (dni name + (.str name "miscellaneous" ) + ((PIPE OS) (IDOC MISC)) + (.str insn ) + (+ opc1 opc2 (f-op-lbit4 op1) (f-op-bit4 op2) (f-data8 op3) (f-op-bit8 op3)) + () + () + ) +) +(sysctrl srstm srst OP1_11 OP2_7 4 8 183 ) +(sysctrl idlem idle OP1_8 OP2_7 7 8 135) +(sysctrl pwrdnm pwrdn OP1_9 OP2_7 6 8 151) +(sysctrl diswdtm diswdt OP1_10 OP2_5 5 10 165) +(sysctrl enwdtm enwdt OP1_8 OP2_5 7 10 133) +(sysctrl einitm einit OP1_11 OP2_5 4 10 181) +(sysctrl srvwdtm srvwdt OP1_10 OP2_7 5 8 167 ) + +;s/w brk +; SBRK +(dni sbrk "sbrk" + ((PIPE OS) (IDOC MISC)) + "sbrk" + (+ OP1_8 OP2_12 (f-op-bit8 0)) + () + () +) + +; atomic sequence +; ATOMIC #irang2 +(dni atomic "begin atomic sequence" + ((PIPE OS) (IDOC SYSC)) + "atomic $hash$uimm2" + (+ OP1_13 OP2_1 (f-op-lbit2 0) uimm2 (f-op-bit4 0)) + (sequence ((HI count)) + (set HI count uimm2) + (cond HI + ((ne HI count (const 0)) + (sequence () + (set HI pc (add HI pc (const 2))) + (set HI count (sub HI count (const 1))) + )) + ) + (set HI count (const 0)) + ) + () +) + +;extended register sequence +; EXTR #irang2 +(dni extr "begin extended register sequence" + ((PIPE OS) (IDOC SYSC)) + "extr $hash$uimm2" + (+ OP1_13 OP2_1 (f-op-lbit2 2) uimm2 (f-op-bit4 0)) + (sequence ((HI count)) + (set HI count uimm2) + (cond HI + ((ne HI count (const 0)) + (sequence () + (set HI pc (add HI pc (const 2))) + (set HI count (sub HI count (const 1))) + )) + ) + (set HI count (const 0)) + ) + () +) + +;extended page sequence +; EXTP Rw,#irang2 +(dni extp "begin extended page sequence" + ((PIPE OS) (IDOC SYSC)) + "extp $sr,$hash$uimm2" + (+ OP1_13 OP2_12 (f-op-lbit2 1) uimm2 sr) + (sequence ((HI count)) + (set HI count uimm2) + (cond HI + ((ne HI count (const 0)) + (sequence () + (set HI pc (add HI pc (const 2))) + (set HI count (sub HI count (const 1))) + )) + ) + (set HI count (const 0)) + ) + () +) + +;extended page sequence +; EXTP #pag10,#irang2 +(dni extp1 "begin extended page sequence" + ((PIPE OS) (IDOC SYSC)) + "extp $hash$pagenum,$hash$uimm2" + (+ OP1_13 OP2_7 (f-op-lbit2 1) uimm2 (f-op-bit4 0) pagenum (f-qlobit 0) (f-qlobit2 0)) + (sequence ((HI count)) + (set HI count uimm2) + (cond HI + ((ne HI count (const 0)) + (sequence () + (set HI pc (add HI pc (const 2))) + (set HI count (sub HI count (const 1))) + )) + ) + (set HI count (const 0)) + ) + () +) + +; EXTP #pag10,#irang2 +(dni extpg1 "begin extended page sequence" + ((PIPE OS) (IDOC SYSC)) + "extp $hash$pag$upag16,$hash$uimm2" + (+ OP1_13 OP2_7 (f-op-lbit2 1) uimm2 (f-op-bit4 0) upag16 ) + (sequence ((HI count)) + (set HI count uimm2) + (cond HI + ((ne HI count (const 0)) + (sequence () + (set HI pc (add HI pc (const 2))) + (set HI count (sub HI count (const 1))) + )) + ) + (set HI count (const 0)) + ) + () +) + +;extended page and register sequence +; EXTPR Rw,#irang2 +(dni extpr "begin extended page and register sequence" + ((PIPE OS) (IDOC SYSC)) + "extpr $sr,$hash$uimm2" + (+ OP1_13 OP2_12 (f-op-lbit2 3) uimm2 sr) + (sequence ((HI count)) + (set HI count uimm2) + (cond HI + ((ne HI count (const 0)) + (sequence () + (set HI pc (add HI pc (const 2))) + (set HI count (sub HI count (const 1))) + )) + ) + (set HI count (const 0)) + ) + () +) + +;extended page and register sequence +; EXTPR #pag10,#irang2 +(dni extpr1 "begin extended page sequence" + ((PIPE OS) (IDOC SYSC)) + "extpr $hash$pagenum,$hash$uimm2" + (+ OP1_13 OP2_7 (f-op-lbit2 3) uimm2 (f-op-bit4 0) pagenum (f-qlobit 0) (f-qlobit2 0)) + (sequence ((HI count)) + (set HI count uimm2) + (cond HI + ((ne HI count (const 0)) + (sequence () + (set HI pc (add HI pc (const 2))) + (set HI count (sub HI count (const 1))) + )) + ) + (set HI count (const 0)) + ) + () +) + +;extended segment sequence +; EXTS Rw,#irang2 +(dni exts "begin extended segment sequence" + ((PIPE OS) (IDOC SYSC)) + "exts $sr,$hash$uimm2" + (+ OP1_13 OP2_12 (f-op-lbit2 0) uimm2 sr) + (sequence ((HI count)) + (set HI count uimm2) + (cond HI + ((ne HI count (const 0)) + (sequence () + (set HI pc (add HI pc (const 2))) + (set HI count (sub HI count (const 1))) + )) + ) + (set HI count (const 0)) + ) + () +) + +;extended segment sequence +; EXTS #seg8,#irang2 +(dni exts1 "begin extended segment sequence" + ((PIPE OS) (IDOC SYSC)) + "exts $hash$seghi8,$hash$uimm2" + (+ OP1_13 OP2_7 (f-op-lbit2 0) uimm2 (f-op-bit4 0) seghi8 (f-op-bit8 0)) + (sequence ((HI count)) + (set HI count uimm2) + (cond HI + ((ne HI count (const 0)) + (sequence () + (set HI pc (add HI pc (const 2))) + (set HI count (sub HI count (const 1))) + )) + ) + (set HI count (const 0)) + ) + () +) + +;extended segment register sequence +; EXTSR Rwm,#irang2 +(dni extsr "begin extended segment and register sequence" + ((PIPE OS) (IDOC SYSC)) + "extsr $sr,$hash$uimm2" + (+ OP1_13 OP2_12 (f-op-lbit2 2) uimm2 sr) + (sequence ((HI count)) + (set HI count uimm2) + (cond HI + ((ne HI count (const 0)) + (sequence () + (set HI pc (add HI pc (const 2))) + (set HI count (sub HI count (const 1))) + )) + ) + (set HI count (const 0)) + ) + () +) + +;extended segment register sequence +; EXTSR #pag10,#irang2 +(dni extsr1 "begin extended segment and register sequence" + ((PIPE OS) (IDOC SYSC)) + "extsr $hash$seghi8,$hash$uimm2" + (+ OP1_13 OP2_7 (f-op-lbit2 2) uimm2 (f-op-bit4 0) seghi8 (f-op-bit8 0)) + (sequence ((HI count)) + (set HI count uimm2) + (cond HI + ((ne HI count (const 0)) + (sequence () + (set HI pc (add HI pc (const 2))) + (set HI count (sub HI count (const 1))) + )) + ) + (set HI count (const 0)) + ) + () +) + +;prioritize register +;PRIOR Rwn,Rwm +(dni prior "add registers" + ((PIPE OS) (IDOC ALU)) + "prior $dr,$sr" + (+ OP1_2 OP2_11 dr sr) + (sequence ((HI count) (HI tmp1) (HI tmp2)) + (set HI count (const 0)) + (set HI tmp1 sr) + (set HI tmp2 (and tmp1 (const 32768))) + (cond HI + ((ne HI tmp2 (const 1)) (ne HI sr (const 0)) + (sll HI tmp1 (const 1)) + (set HI tmp2 (and tmp1 (const 32768))) + (set HI count (add HI count (const 1))) + ) + ) + (set HI dr count) + ) + () +) + + +;bit instructions +;****************************************************************** +;bit clear +(define-pmacro (bclear name insn opc1) + (dni name + (.str name "bit clear" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $reg8$dot$qbit") + (+ opc1 OP2_14 reg8) + (sequence ((HI tmp1) (HI tmp2)) + (set tmp2 (const 1)) + (set tmp1 reg8) + ;; FIXME: (sll tmp2 qbit) + ;; FIXME: (inv tmp2) + (set BI tmp1(and tmp1 tmp2)) + (set HI reg8 tmp1)) + () + ) +) + +;clear direct bit +(dni bclr18 "bit logical MOVN" + ((PIPE OS) (IDOC ALU)) + "bclr $RegNam" + (+ OP1_11 OP2_14 RegNam) + (sequence ((HI tmp1) (HI tmp2)) + (set tmp2 (const 1)) + (set tmp1 reg8) + ;; FIXME: (sll tmp2 qbit) + ;; FIXME: (inv tmp2) + (set BI tmp1(and tmp1 tmp2)) + (set HI reg8 tmp1)) + () +) + + +(bclear bclr0 bclr QBIT_0 ) +(bclear bclr1 bclr QBIT_1 ) +(bclear bclr2 bclr QBIT_2 ) +(bclear bclr3 bclr QBIT_3 ) +(bclear bclr4 bclr QBIT_4 ) +(bclear bclr5 bclr QBIT_5 ) +(bclear bclr6 bclr QBIT_6 ) +(bclear bclr7 bclr QBIT_7 ) +(bclear bclr8 bclr QBIT_8 ) +(bclear bclr9 bclr QBIT_9 ) +(bclear bclr10 bclr QBIT_10 ) +(bclear bclr11 bclr QBIT_11 ) +(bclear bclr12 bclr QBIT_12 ) +(bclear bclr13 bclr QBIT_13 ) +(bclear bclr14 bclr QBIT_14 ) +(bclear bclr15 bclr QBIT_15 ) + +;set direct bit +(dni bset19 "bit logical MOVN" + ((PIPE OS) (IDOC ALU)) + "bset $RegNam" + (+ OP1_11 OP2_15 RegNam) + (sequence ((HI tmp1) (HI tmp2)) + (set tmp2 (const 1)) + (set tmp1 reg8) + ;; FIXME: (sll tmp2 qbit) + (set BI tmp1(or tmp1 tmp2)) + (set HI reg8 tmp1)) + () +) + +;bit set +(define-pmacro (bitset name insn opc1) + (dni name + (.str name "bit set" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $reg8$dot$qbit") + (+ opc1 OP2_15 reg8) + (sequence ((HI tmp1) (HI tmp2)) + (set tmp2 (const 1)) + (set tmp1 reg8) + ;; FIXME: (sll tmp2 qbit) + (set BI tmp1(or tmp1 tmp2)) + (set HI reg8 tmp1)) + () + ) +) + + +(bitset bset0 bset QBIT_0 ) +(bitset bset1 bset QBIT_1 ) +(bitset bset2 bset QBIT_2 ) +(bitset bset3 bset QBIT_3 ) +(bitset bset4 bset QBIT_4 ) +(bitset bset5 bset QBIT_5 ) +(bitset bset6 bset QBIT_6 ) +(bitset bset7 bset QBIT_7 ) +(bitset bset8 bset QBIT_8 ) +(bitset bset9 bset QBIT_9 ) +(bitset bset10 bset QBIT_10 ) +(bitset bset11 bset QBIT_11 ) +(bitset bset12 bset QBIT_12 ) +(bitset bset13 bset QBIT_13 ) +(bitset bset14 bset QBIT_14 ) +(bitset bset15 bset QBIT_15 ) + +;mov direct bit +;BMOV bitaddrZ.z,bitaddrQ.q +(dni bmov "bit logical MOV" + ((PIPE OS) (IDOC ALU)) + "bmov $reghi8$dot$qhibit,$reg8$dot$qlobit" + (+ OP1_4 OP2_10 reg8 reghi8 qhibit qlobit) + (sequence ((HI tmp1) (HI tmp2) (HI tmp3) (HI tmp4)) + (set HI tmp1 reghi8) + (set HI tmp2 reg8) + (set tmp3 (const 1)) + (set tmp4 (const 1)) + ;; FIXME: (sll tmp3 qlobit) + ;; FIXME: (sll tmp4 qhibit) + ;; FIXME: (and tmp1 tmp3) + ;; FIXME: (and tmp2 tmp4) + (set BI tmp1 tmp2) + (set HI reghi8 tmp1) + (set HI reg8 tmp2)) + () +) + +;movn direct bit +;BMOVN bitaddrZ.z,bitaddrQ.q +(dni bmovn "bit logical MOVN" + ((PIPE OS) (IDOC ALU)) + "bmovn $reghi8$dot$qhibit,$reg8$dot$qlobit" + (+ OP1_3 OP2_10 reg8 reghi8 qhibit qlobit) + (sequence ((HI tmp1) (HI tmp2) (HI tmp3) (HI tmp4)) + (set HI tmp1 reghi8) + (set HI tmp2 reg8) + (set tmp3 (const 1)) + (set tmp4 (const 1)) + ;; FIXME: (sll tmp3 qlobit) + ;; FIXME: (sll tmp4 qhibit) + ;; FIXME: (and tmp1 tmp3) + ;; FIXME: (and tmp2 tmp4) + ;; FIXME: (inv HI tmp2) + (set BI tmp1 tmp2) + (set HI reghi8 tmp1) + (set HI reg8 tmp2)) + () +) + +;and direct bit +;BAND bitaddrZ.z,bitaddrQ.q +(dni band "bit logical AND" + ((PIPE OS) (IDOC ALU)) + "band $reghi8$dot$qhibit,$reg8$dot$qlobit" + (+ OP1_6 OP2_10 reg8 reghi8 qhibit qlobit) + (sequence ((HI tmp1) (HI tmp2) (HI tmp3) (HI tmp4)) + (set HI tmp1 reghi8) + (set HI tmp2 reg8) + (set tmp3 (const 1)) + (set tmp4 (const 1)) + ;; FIXME: (sll tmp3 qlobit) + ;; FIXME: (sll tmp4 qhibit) + ;; FIXME: (and tmp1 tmp3) + ;; FIXME: (and tmp2 tmp4) + (set BI tmp1(and tmp1 tmp2)) + (set HI reghi8 tmp1) + (set HI reg8 tmp2)) + () +) + +;or direct bit +;BOR bitaddrZ.z,bitaddrQ.q +(dni bor "bit logical OR" + ((PIPE OS) (IDOC ALU)) + "bor $reghi8$dot$qhibit,$reg8$dot$qlobit" + (+ OP1_5 OP2_10 reg8 reghi8 qhibit qlobit) + (sequence ((HI tmp1) (HI tmp2) (HI tmp3) (HI tmp4)) + (set HI tmp1 reghi8) + (set HI tmp2 reg8) + (set tmp3 (const 1)) + (set tmp4 (const 1)) + ;; FIXME: (sll tmp3 qlobit) + ;; FIXME: (sll tmp4 qhibit) + ;; FIXME: (and tmp1 tmp3) + ;; FIXME: (and tmp2 tmp4) + (set BI tmp1(or tmp1 tmp2)) + (set HI reghi8 tmp1) + (set HI reg8 tmp2)) + () +) + +;xor direct bit +;BXOR bitaddrZ.z,bitaddrQ.q +(dni bxor "bit logical XOR" + ((PIPE OS) (IDOC ALU)) + "bxor $reghi8$dot$qhibit,$reg8$dot$qlobit" + (+ OP1_7 OP2_10 reg8 reghi8 qhibit qlobit) + (sequence ((HI tmp1) (HI tmp2) (HI tmp3) (HI tmp4)) + (set HI tmp1 reghi8) + (set HI tmp2 reg8) + (set tmp3 (const 1)) + (set tmp4 (const 1)) + ;; FIXME: (sll tmp3 qlobit) + ;; FIXME: (sll tmp4 qhibit) + ;; FIXME: (and tmp1 tmp3) + ;; FIXME: (and tmp2 tmp4) + (set BI tmp1(xor tmp1 tmp2)) + (set HI reghi8 tmp1) + (set HI reg8 tmp2)) + () +) + +;cmp direct bit to bit +;BCMP bitaddrZ.z,bitaddrQ.q +(dni bcmp "bit to bit compare" + ((PIPE OS) (IDOC ALU)) + "bcmp $reghi8$dot$qhibit,$reg8$dot$qlobit" + (+ OP1_2 OP2_10 reg8 reghi8 qhibit qlobit) + (sequence ((HI tmp1) (HI tmp2) (HI tmp3) (HI tmp4)) + (set HI tmp1 reghi8) + (set HI tmp2 reg8) + (set tmp3 (const 1)) + (set tmp4 (const 1)) + ;; FIXME: (sll tmp3 qlobit) + ;; FIXME: (sll tmp4 qhibit) + ;; FIXME: (and tmp1 tmp3) + ;; FIXME: (and tmp2 tmp4) + (set BI tmp1(xor tmp1 tmp2)) + (set HI reghi8 tmp1) + (set HI reg8 tmp2)) + () +) + +;bit field low byte +;BFLDL op1,op2,op3 +(dni bfldl "bit field low byte" + ((PIPE OS) (IDOC MOVE)) + "bfldl $reg8,$hash$mask8,$hash$datahi8" + (+ OP1_0 OP2_10 reg8 mask8 datahi8) + (sequence ((HI tmp1) (QI tmp2) (QI tmp3)) + (set HI tmp1 reg8) + (set QI tmp2 mask8) + (set QI tmp3 datahi8) + ;; FIXME: (inv QI tmp2) + (set HI tmp1 (and tmp1 tmp2)) + (set HI tmp1 (or tmp1 tmp3)) + (set HI reg8 tmp1) + ) + () +) + +;bit field high byte +;BFLDH op1,op2,op3 +(dni bfldh "bit field high byte" + ((PIPE OS) (IDOC MOVE)) + "bfldh $reg8,$hash$masklo8,$hash$data8" + (+ OP1_1 OP2_10 reg8 masklo8 data8) + (sequence ((HI tmp1) (HI tmp2) (HI tmp3)) + (set HI tmp1 reg8) + (set QI tmp2 masklo8) + (set HI tmp3 data8) + ;; FIXME: (sll tmp2 (const 8)) + ;; FIXME: (inv HI tmp2) + ;; FIXME: (sll tmp3 (const 8)) + (set HI tmp1 (and tmp1 tmp2)) + (set HI tmp1 (or tmp1 tmp3)) + (set HI reg8 tmp1) + ) + () +) + +;/**********compare instructions****************** + +;Compare register +;CMP Rwn,Rwm +(dni cmpr "compare two registers" + ((PIPE OS) (IDOC CMP)) + "cmp $src1,$src2" + (+ OP1_4 OP2_0 src1 src2) + (set condbit (lt HI src1 src2)) + () +) + +;Compare byte register +;CMPB Rbn,Rbm +(dni cmpbr "compare two byte registers" + ((PIPE OS) (IDOC CMP)) + "cmpb $drb,$srb" + (+ OP1_4 OP2_1 drb srb) + (set condbit (lt QI drb srb)) + () +) + +(define-pmacro (cmp1 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "compare" ) + ((PIPE OS) (IDOC CMP)) + (.str insn " $"op1 ",$hash$"op2) + (+ opc1 opc2 op1 (f-op-bit1 0) op2) + (set condbit (lt mode op1 op2)) + () + ) +) +(cmp1 cmpri cmp OP1_4 OP2_8 src1 uimm3 HI) +(cmp1 cmpbri cmpb OP1_4 OP2_9 drb uimm3 QI) + +; CMP Rwn,#data16 +(dni cmpi "compare" + ((PIPE OS) (IDOC CMP)) + "cmp $reg8,$hash$uimm16" + (+ OP1_4 OP2_6 reg8 uimm16) + (set condbit (lt HI reg8 uimm16)) + () +) + +; CMPB reg,#data8 +(dni cmpbi "compare" + ((PIPE OS) (IDOC CMP)) + "cmpb $regb8,$hash$uimm8" + (+ OP1_4 OP2_7 regb8 uimm8 (f-op-bit8 0)) + (set condbit (lt QI regb8 uimm8)) + () +) + +;compare reg and indirect memory +(define-pmacro (cmp2 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "compare" ) + ((PIPE OS) (IDOC CMP)) + (.str insn " $"op1 ",[$"op2"]") + (+ opc1 opc2 op1 (f-op-bit2 2) op2) + (set condbit (lt mode op1 op2)) + () + ) +) +(cmp2 cmpr2 cmp OP1_4 OP2_8 dr sr2 HI) +(cmp2 cmpbr2 cmpb OP1_4 OP2_9 drb sr2 QI) + +;compare register and indirect memory post increment +(define-pmacro (cmp3 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "compare" ) + ((PIPE OS) (IDOC CMP)) + (.str insn " $"op1 ",[$"op2"+]") + (+ opc1 opc2 op1 (f-op-bit2 3) op2) + (sequence () + (set condbit (lt mode op1 op2)) + (set HI op2 (add HI op2 (const 2))) + ) + () + ) +) +(cmp3 cmp2i cmp OP1_4 OP2_8 dr sr2 HI) +(cmp3 cmpb2i cmpb OP1_4 OP2_9 drb sr2 QI) + +;compare register and direct memory +(define-pmacro (cmp4 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "compare" ) + ((PIPE OS) (IDOC CMP)) + (.str insn " $"op1 ",$pof$"op2) + (+ opc1 opc2 op1 op2) + (set condbit (lt HI op1 (mem HI op2))) + () + ) +) +(cmp4 cmp04 cmp OP1_4 OP2_2 reg8 upof16 HI) +(cmp4 cmpb4 cmpb OP1_4 OP2_3 regb8 upof16 QI) + +;compare register and direct memory +(define-pmacro (cmp4 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "compare" ) + ((PIPE OS) (IDOC CMP)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op1 op2) + (set condbit (lt HI op1 (mem HI op2))) + () + ) +) +(cmp4 cmp004 cmp OP1_4 OP2_2 regmem8 memgr8 HI) +(cmp4 cmp0004 cmp OP1_4 OP2_2 reg8 memory HI) +(cmp4 cmpb04 cmpb OP1_4 OP2_3 regbmem8 memgr8 QI) +(cmp4 cmpb004 cmpb OP1_4 OP2_3 regb8 memory QI) + +;compare register and immediate +(define-pmacro (cmp5 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "compare" ) + ((PIPE OS) (IDOC CMP)) + (.str insn " $"op1 ",$hash$"op2) + (+ opc1 opc2 op2 op1) + (sequence () + (set condbit (lt HI op1 op2)) + (set mode op1 (sub HI op1 (const 1))) + ) + () + ) +) +(cmp5 cmpd1ri cmpd1 OP1_10 OP2_0 sr uimm4 HI) +(cmp5 cmpd2ri cmpd2 OP1_11 OP2_0 sr uimm4 HI) +(cmp5 cmpi1ri cmpi1 OP1_8 OP2_0 sr uimm4 HI) +(cmp5 cmpi2ri cmpi2 OP1_9 OP2_0 sr uimm4 HI) +(cmp5 cmpd1rim cmpd1 OP1_10 OP2_6 reg8 uimm16 HI) +(cmp5 cmpd2rim cmpd2 OP1_11 OP2_6 reg8 uimm16 HI) +(cmp5 cmpi1rim cmpi1 OP1_8 OP2_6 reg8 uimm16 HI) +(cmp5 cmpi2rim cmpi2 OP1_9 OP2_6 reg8 uimm16 HI) + +;compare register and direct memory +(define-pmacro (cmp6 name insn opc1 opc2 op1 op2 mode ) + (dni name + (.str name "compare" ) + ((PIPE OS) (IDOC CMP)) + (.str insn " $"op1 ",$pof$"op2) + (+ opc1 opc2 op1 op2) + (sequence () + (set condbit (lt HI op1 (mem HI op2))) + (set mode op1 (sub HI op1 (const 1))) + ) + () + ) +) +(cmp6 cmpd1rp cmpd1 OP1_10 OP2_2 reg8 upof16 HI ) +(cmp6 cmpd2rp cmpd2 OP1_11 OP2_2 reg8 upof16 HI ) +(cmp6 cmpi1rp cmpi1 OP1_8 OP2_2 reg8 upof16 HI ) +(cmp6 cmpi2rp cmpi2 OP1_9 OP2_2 reg8 upof16 HI ) + +;compare register and direct memory +(define-pmacro (cmp7 name insn opc1 opc2 op1 op2 mode) + (dni name + (.str name "compare" ) + ((PIPE OS) (IDOC CMP)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op1 op2) + (sequence () + (set condbit (lt HI op1 (mem HI op2))) + (set mode op1 (sub HI op1 (const 1))) + ) + () + ) +) +(cmp7 cmpd1rm cmpd1 OP1_10 OP2_2 regmem8 memgr8 HI) +(cmp7 cmpd2rm cmpd2 OP1_11 OP2_2 regmem8 memgr8 HI) +(cmp7 cmpi1rm cmpi1 OP1_8 OP2_2 regmem8 memgr8 HI) +(cmp7 cmpi2rm cmpi2 OP1_9 OP2_2 regmem8 memgr8 HI) +(cmp7 cmpd1rmi cmpd1 OP1_10 OP2_2 reg8 memory HI) +(cmp7 cmpd2rmi cmpd2 OP1_11 OP2_2 reg8 memory HI) +(cmp7 cmpi1rmi cmpi1 OP1_8 OP2_2 reg8 memory HI) +(cmp7 cmpi2rmi cmpi2 OP1_9 OP2_2 reg8 memory HI) + + +;Shift and rotate insns +;**************************************************************** +(define-pmacro (shift name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "shift" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$"op2) + (+ opc1 opc2 op1 op2) + (set mode op1 (insn1 mode op1 op2)) + () + ) +) +(shift shlr shl sll OP1_4 OP2_12 dr sr HI) +(shift shrr shr srl OP1_6 OP2_12 dr sr HI) +(shift rolr rol rol OP1_0 OP2_12 dr sr HI) +(shift rorr ror ror OP1_2 OP2_12 dr sr HI) +(shift ashrr ashr sra OP1_10 OP2_12 dr sr HI) + +(define-pmacro (shift1 name insn insn1 opc1 opc2 op1 op2 mode) + (dni name + (.str name "shift" ) + ((PIPE OS) (IDOC ALU)) + (.str insn " $"op1 ",$hash$"op2) + (+ opc1 opc2 op2 op1) + (set mode op1 (insn1 mode op1 op2)) + () + ) +) +(shift1 shlri shl sll OP1_5 OP2_12 sr uimm4 HI) +(shift1 shrri shr srl OP1_7 OP2_12 sr uimm4 HI) +(shift1 rolri rol rol OP1_1 OP2_12 sr uimm4 HI) +(shift1 rorri ror ror OP1_3 OP2_12 sr uimm4 HI) +(shift1 ashrri ashr sra OP1_11 OP2_12 sr uimm4 HI) diff --git a/cpu/xc16x.opc b/cpu/xc16x.opc new file mode 100644 index 00000000000..455f3fb4728 --- /dev/null +++ b/cpu/xc16x.opc @@ -0,0 +1,245 @@ +/* XC16X opcode support. -*- C -*- + + Copyright 2006, 2007, 2009 Free Software Foundation, Inc. + + Contributed by KPIT Cummins Infosystems Ltd.; developed under contract + from Infineon Systems, GMBH , Germany. + + 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + + +/* This file is an addendum to xc16x.cpu. Heavy use of C code isn't + appropriate in .cpu files, so it resides here. This especially applies + to assembly/disassembly where parsing/printing can be quite involved. + Such things aren't really part of the specification of the cpu, per se, + so .cpu files provide the general framework and .opc files handle the + nitty-gritty details as necessary. + + Each section is delimited with start and end markers. + + <arch>-opc.h additions use: "-- opc.h" + <arch>-opc.c additions use: "-- opc.c" + <arch>-asm.c additions use: "-- asm.c" + <arch>-dis.c additions use: "-- dis.c" + <arch>-ibd.h additions use: "-- ibd.h" */ + +/* -- opc.h */ + +#define CGEN_DIS_HASH_SIZE 8 +#define CGEN_DIS_HASH(buf,value) (((* (unsigned char*) (buf)) >> 3) % CGEN_DIS_HASH_SIZE) + +/* -- */ + +/* -- opc.c */ + +/* -- */ + +/* -- asm.c */ +/* Handle '#' prefixes (i.e. skip over them). */ + +static const char * +parse_hash (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + const char **strp, + int opindex ATTRIBUTE_UNUSED, + long *valuep ATTRIBUTE_UNUSED) +{ + if (**strp == '#') + { + ++*strp; + return NULL; + } + return _("Missing '#' prefix"); +} + +/* Handle '.' prefixes (i.e. skip over them). */ + +static const char * +parse_dot (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + const char **strp, + int opindex ATTRIBUTE_UNUSED, + long *valuep ATTRIBUTE_UNUSED) +{ + if (**strp == '.') + { + ++*strp; + return NULL; + } + return _("Missing '.' prefix"); +} + +/* Handle 'pof:' prefixes (i.e. skip over them). */ + +static const char * +parse_pof (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + const char **strp, + int opindex ATTRIBUTE_UNUSED, + long *valuep ATTRIBUTE_UNUSED) +{ + if (strncasecmp (*strp, "pof:", 4) == 0) + { + *strp += 4; + return NULL; + } + return _("Missing 'pof:' prefix"); +} + +/* Handle 'pag:' prefixes (i.e. skip over them). */ + +static const char * +parse_pag (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + const char **strp, + int opindex ATTRIBUTE_UNUSED, + long *valuep ATTRIBUTE_UNUSED) +{ + if (strncasecmp (*strp, "pag:", 4) == 0) + { + *strp += 4; + return NULL; + } + return _("Missing 'pag:' prefix"); +} + +/* Handle 'sof' prefixes (i.e. skip over them). */ + +static const char * +parse_sof (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + const char **strp, + int opindex ATTRIBUTE_UNUSED, + long *valuep ATTRIBUTE_UNUSED) +{ + if (strncasecmp (*strp, "sof:", 4) == 0) + { + *strp += 4; + return NULL; + } + return _("Missing 'sof:' prefix"); +} + +/* Handle 'seg' prefixes (i.e. skip over them). */ + +static const char * +parse_seg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + const char **strp, + int opindex ATTRIBUTE_UNUSED, + long *valuep ATTRIBUTE_UNUSED) +{ + if (strncasecmp (*strp, "seg:", 4) == 0) + { + *strp += 4; + return NULL; + } + return _("Missing 'seg:' prefix"); +} +/* -- */ + +/* -- dis.c */ + +#define CGEN_PRINT_NORMAL(cd, info, value, attrs, pc, length) \ + do \ + { \ + if (CGEN_BOOL_ATTR ((attrs), CGEN_OPERAND_DOT_PREFIX)) \ + info->fprintf_func (info->stream, "."); \ + if (CGEN_BOOL_ATTR ((attrs), CGEN_OPERAND_POF_PREFIX)) \ + info->fprintf_func (info->stream, "#pof:"); \ + if (CGEN_BOOL_ATTR ((attrs), CGEN_OPERAND_PAG_PREFIX)) \ + info->fprintf_func (info->stream, "#pag:"); \ + } \ + while (0) + +/* Print a 'pof:' prefix to an operand. */ + +static void +print_pof (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info ATTRIBUTE_UNUSED, + long value ATTRIBUTE_UNUSED, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ +} + +/* Print a 'pag:' prefix to an operand. */ + +static void +print_pag (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info ATTRIBUTE_UNUSED, + long value ATTRIBUTE_UNUSED, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ +} + +/* Print a 'sof:' prefix to an operand. */ + +static void +print_sof (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value ATTRIBUTE_UNUSED, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + disassemble_info *info = (disassemble_info *) dis_info; + + info->fprintf_func (info->stream, "sof:"); +} + +/* Print a 'seg:' prefix to an operand. */ + +static void +print_seg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value ATTRIBUTE_UNUSED, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + disassemble_info *info = (disassemble_info *) dis_info; + + info->fprintf_func (info->stream, "seg:"); +} + +/* Print a '#' prefix to an operand. */ + +static void +print_hash (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info, + long value ATTRIBUTE_UNUSED, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ + disassemble_info *info = (disassemble_info *) dis_info; + + info->fprintf_func (info->stream, "#"); +} + +/* Print a '.' prefix to an operand. */ + +static void +print_dot (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void * dis_info ATTRIBUTE_UNUSED, + long value ATTRIBUTE_UNUSED, + unsigned int attrs ATTRIBUTE_UNUSED, + bfd_vma pc ATTRIBUTE_UNUSED, + int length ATTRIBUTE_UNUSED) +{ +} + +/* -- */ |