Commit aa0aa4fa31054a9488fd49c29c6ab12e2e85be58
1 parent
84fa15d8
added ARM and Sparc disassemblers
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@214 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
6 changed files
with
5008 additions
and
89 deletions
arm-dis.c
0 → 100644
| 1 | +/* Instruction printing code for the ARM | |
| 2 | + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 | |
| 3 | + Free Software Foundation, Inc. | |
| 4 | + Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) | |
| 5 | + Modification by James G. Smith (jsmith@cygnus.co.uk) | |
| 6 | + | |
| 7 | +This file is part of libopcodes. | |
| 8 | + | |
| 9 | +This program is free software; you can redistribute it and/or modify it under | |
| 10 | +the terms of the GNU General Public License as published by the Free | |
| 11 | +Software Foundation; either version 2 of the License, or (at your option) | |
| 12 | +any later version. | |
| 13 | + | |
| 14 | +This program is distributed in the hope that it will be useful, but WITHOUT | |
| 15 | +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 16 | +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
| 17 | +more details. | |
| 18 | + | |
| 19 | +You should have received a copy of the GNU General Public License | |
| 20 | +along with this program; if not, write to the Free Software | |
| 21 | +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
| 22 | + | |
| 23 | +#include "dis-asm.h" | |
| 24 | + | |
| 25 | +struct arm_opcode { | |
| 26 | + unsigned long value, mask; /* recognise instruction if (op&mask)==value */ | |
| 27 | + char *assembler; /* how to disassemble this instruction */ | |
| 28 | +}; | |
| 29 | + | |
| 30 | +struct thumb_opcode | |
| 31 | +{ | |
| 32 | + unsigned short value, mask; /* recognise instruction if (op&mask)==value */ | |
| 33 | + char * assembler; /* how to disassemble this instruction */ | |
| 34 | +}; | |
| 35 | + | |
| 36 | +/* format of the assembler string : | |
| 37 | + | |
| 38 | + %% % | |
| 39 | + %<bitfield>d print the bitfield in decimal | |
| 40 | + %<bitfield>x print the bitfield in hex | |
| 41 | + %<bitfield>X print the bitfield as 1 hex digit without leading "0x" | |
| 42 | + %<bitfield>r print as an ARM register | |
| 43 | + %<bitfield>f print a floating point constant if >7 else a | |
| 44 | + floating point register | |
| 45 | + %<code>y print a single precision VFP reg. | |
| 46 | + Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair | |
| 47 | + %<code>z print a double precision VFP reg | |
| 48 | + Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list | |
| 49 | + %c print condition code (always bits 28-31) | |
| 50 | + %P print floating point precision in arithmetic insn | |
| 51 | + %Q print floating point precision in ldf/stf insn | |
| 52 | + %R print floating point rounding mode | |
| 53 | + %<bitnum>'c print specified char iff bit is one | |
| 54 | + %<bitnum>`c print specified char iff bit is zero | |
| 55 | + %<bitnum>?ab print a if bit is one else print b | |
| 56 | + %p print 'p' iff bits 12-15 are 15 | |
| 57 | + %t print 't' iff bit 21 set and bit 24 clear | |
| 58 | + %o print operand2 (immediate or register + shift) | |
| 59 | + %a print address for ldr/str instruction | |
| 60 | + %s print address for ldr/str halfword/signextend instruction | |
| 61 | + %b print branch destination | |
| 62 | + %B print arm BLX(1) destination | |
| 63 | + %A print address for ldc/stc/ldf/stf instruction | |
| 64 | + %m print register mask for ldm/stm instruction | |
| 65 | + %C print the PSR sub type. | |
| 66 | + %F print the COUNT field of a LFM/SFM instruction. | |
| 67 | +Thumb specific format options: | |
| 68 | + %D print Thumb register (bits 0..2 as high number if bit 7 set) | |
| 69 | + %S print Thumb register (bits 3..5 as high number if bit 6 set) | |
| 70 | + %<bitfield>I print bitfield as a signed decimal | |
| 71 | + (top bit of range being the sign bit) | |
| 72 | + %M print Thumb register mask | |
| 73 | + %N print Thumb register mask (with LR) | |
| 74 | + %O print Thumb register mask (with PC) | |
| 75 | + %T print Thumb condition code (always bits 8-11) | |
| 76 | + %I print cirrus signed shift immediate: bits 0..3|4..6 | |
| 77 | + %<bitfield>B print Thumb branch destination (signed displacement) | |
| 78 | + %<bitfield>W print (bitfield * 4) as a decimal | |
| 79 | + %<bitfield>H print (bitfield * 2) as a decimal | |
| 80 | + %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol | |
| 81 | +*/ | |
| 82 | + | |
| 83 | +/* Note: There is a partial ordering in this table - it must be searched from | |
| 84 | + the top to obtain a correct match. */ | |
| 85 | + | |
| 86 | +static struct arm_opcode arm_opcodes[] = | |
| 87 | +{ | |
| 88 | + /* ARM instructions. */ | |
| 89 | + {0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"}, | |
| 90 | + {0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"}, | |
| 91 | + {0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"}, | |
| 92 | + {0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"}, | |
| 93 | + {0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"}, | |
| 94 | + {0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"}, | |
| 95 | + {0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"}, | |
| 96 | + | |
| 97 | + /* V5J instruction. */ | |
| 98 | + {0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"}, | |
| 99 | + | |
| 100 | + /* XScale instructions. */ | |
| 101 | + {0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"}, | |
| 102 | + {0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"}, | |
| 103 | + {0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"}, | |
| 104 | + {0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"}, | |
| 105 | + {0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"}, | |
| 106 | + {0xf450f000, 0xfc70f000, "pld\t%a"}, | |
| 107 | + | |
| 108 | + /* V5 Instructions. */ | |
| 109 | + {0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"}, | |
| 110 | + {0xfa000000, 0xfe000000, "blx\t%B"}, | |
| 111 | + {0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"}, | |
| 112 | + {0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"}, | |
| 113 | + {0xfc100000, 0xfe100000, "ldc2%22'l\t%8-11d, cr%12-15d, %A"}, | |
| 114 | + {0xfc000000, 0xfe100000, "stc2%22'l\t%8-11d, cr%12-15d, %A"}, | |
| 115 | + {0xfe000000, 0xff000010, "cdp2\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"}, | |
| 116 | + {0xfe000010, 0xff100010, "mcr2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, | |
| 117 | + {0xfe100010, 0xff100010, "mrc2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, | |
| 118 | + | |
| 119 | + /* V5E "El Segundo" Instructions. */ | |
| 120 | + {0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"}, | |
| 121 | + {0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"}, | |
| 122 | + {0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, | |
| 123 | + {0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, | |
| 124 | + {0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, | |
| 125 | + {0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, | |
| 126 | + | |
| 127 | + {0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, | |
| 128 | + {0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, | |
| 129 | + | |
| 130 | + {0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, | |
| 131 | + {0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, | |
| 132 | + {0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, | |
| 133 | + {0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, | |
| 134 | + | |
| 135 | + {0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"}, | |
| 136 | + {0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"}, | |
| 137 | + {0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"}, | |
| 138 | + {0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"}, | |
| 139 | + | |
| 140 | + {0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"}, | |
| 141 | + {0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"}, | |
| 142 | + | |
| 143 | + {0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"}, | |
| 144 | + {0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"}, | |
| 145 | + {0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"}, | |
| 146 | + {0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"}, | |
| 147 | + | |
| 148 | + {0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, | |
| 149 | + {0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, | |
| 150 | + | |
| 151 | + /* ARM Instructions. */ | |
| 152 | + {0x00000090, 0x0e100090, "str%c%6's%5?hb\t%12-15r, %s"}, | |
| 153 | + {0x00100090, 0x0e100090, "ldr%c%6's%5?hb\t%12-15r, %s"}, | |
| 154 | + {0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"}, | |
| 155 | + {0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"}, | |
| 156 | + {0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"}, | |
| 157 | + {0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"}, | |
| 158 | + {0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"}, | |
| 159 | + {0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"}, | |
| 160 | + {0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"}, | |
| 161 | + {0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"}, | |
| 162 | + {0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"}, | |
| 163 | + {0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"}, | |
| 164 | + {0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"}, | |
| 165 | + {0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"}, | |
| 166 | + {0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"}, | |
| 167 | + {0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"}, | |
| 168 | + {0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"}, | |
| 169 | + {0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"}, | |
| 170 | + {0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"}, | |
| 171 | + {0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"}, | |
| 172 | + {0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"}, | |
| 173 | + {0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"}, | |
| 174 | + {0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"}, | |
| 175 | + {0x06000010, 0x0e000010, "undefined"}, | |
| 176 | + {0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"}, | |
| 177 | + {0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"}, | |
| 178 | + {0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"}, | |
| 179 | + {0x0a000000, 0x0e000000, "b%24'l%c\t%b"}, | |
| 180 | + {0x0f000000, 0x0f000000, "swi%c\t%0-23x"}, | |
| 181 | + | |
| 182 | + /* Floating point coprocessor (FPA) instructions */ | |
| 183 | + {0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"}, | |
| 184 | + {0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"}, | |
| 185 | + {0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"}, | |
| 186 | + {0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"}, | |
| 187 | + {0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"}, | |
| 188 | + {0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"}, | |
| 189 | + {0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"}, | |
| 190 | + {0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"}, | |
| 191 | + {0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"}, | |
| 192 | + {0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"}, | |
| 193 | + {0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"}, | |
| 194 | + {0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"}, | |
| 195 | + {0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"}, | |
| 196 | + {0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"}, | |
| 197 | + {0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"}, | |
| 198 | + {0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"}, | |
| 199 | + {0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"}, | |
| 200 | + {0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"}, | |
| 201 | + {0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"}, | |
| 202 | + {0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"}, | |
| 203 | + {0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"}, | |
| 204 | + {0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"}, | |
| 205 | + {0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"}, | |
| 206 | + {0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"}, | |
| 207 | + {0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"}, | |
| 208 | + {0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"}, | |
| 209 | + {0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"}, | |
| 210 | + {0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"}, | |
| 211 | + {0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"}, | |
| 212 | + {0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"}, | |
| 213 | + {0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"}, | |
| 214 | + {0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"}, | |
| 215 | + {0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"}, | |
| 216 | + {0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"}, | |
| 217 | + {0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"}, | |
| 218 | + {0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"}, | |
| 219 | + {0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"}, | |
| 220 | + {0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"}, | |
| 221 | + {0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"}, | |
| 222 | + {0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"}, | |
| 223 | + {0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"}, | |
| 224 | + {0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"}, | |
| 225 | + {0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"}, | |
| 226 | + | |
| 227 | + /* Floating point coprocessor (VFP) instructions */ | |
| 228 | + {0x0eb00bc0, 0x0fff0ff0, "fabsd%c\t%1z, %0z"}, | |
| 229 | + {0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%1y, %0y"}, | |
| 230 | + {0x0e300b00, 0x0ff00ff0, "faddd%c\t%1z, %2z, %0z"}, | |
| 231 | + {0x0e300a00, 0x0fb00f50, "fadds%c\t%1y, %2y, %1y"}, | |
| 232 | + {0x0eb40b40, 0x0fff0f70, "fcmp%7'ed%c\t%1z, %0z"}, | |
| 233 | + {0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%1y, %0y"}, | |
| 234 | + {0x0eb50b40, 0x0fff0f70, "fcmp%7'ezd%c\t%1z"}, | |
| 235 | + {0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%1y"}, | |
| 236 | + {0x0eb00b40, 0x0fff0ff0, "fcpyd%c\t%1z, %0z"}, | |
| 237 | + {0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%1y, %0y"}, | |
| 238 | + {0x0eb70ac0, 0x0fff0fd0, "fcvtds%c\t%1z, %0y"}, | |
| 239 | + {0x0eb70bc0, 0x0fbf0ff0, "fcvtsd%c\t%1y, %0z"}, | |
| 240 | + {0x0e800b00, 0x0ff00ff0, "fdivd%c\t%1z, %2z, %0z"}, | |
| 241 | + {0x0e800a00, 0x0fb00f50, "fdivs%c\t%1y, %2y, %0y"}, | |
| 242 | + {0x0d100b00, 0x0f700f00, "fldd%c\t%1z, %A"}, | |
| 243 | + {0x0c900b00, 0x0fd00f00, "fldmia%0?xd%c\t%16-19r%21'!, %3z"}, | |
| 244 | + {0x0d300b00, 0x0ff00f00, "fldmdb%0?xd%c\t%16-19r!, %3z"}, | |
| 245 | + {0x0d100a00, 0x0f300f00, "flds%c\t%1y, %A"}, | |
| 246 | + {0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %3y"}, | |
| 247 | + {0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %3y"}, | |
| 248 | + {0x0e000b00, 0x0ff00ff0, "fmacd%c\t%1z, %2z, %0z"}, | |
| 249 | + {0x0e000a00, 0x0fb00f50, "fmacs%c\t%1y, %2y, %0y"}, | |
| 250 | + {0x0e200b10, 0x0ff00fff, "fmdhr%c\t%2z, %12-15r"}, | |
| 251 | + {0x0e000b10, 0x0ff00fff, "fmdlr%c\t%2z, %12-15r"}, | |
| 252 | + {0x0c400b10, 0x0ff00ff0, "fmdrr%c\t%0z, %12-15r, %16-19r"}, | |
| 253 | + {0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %2z"}, | |
| 254 | + {0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %2z"}, | |
| 255 | + {0x0c500b10, 0x0ff00ff0, "fmrrd%c\t%12-15r, %16-19r, %0z"}, | |
| 256 | + {0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %4y"}, | |
| 257 | + {0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %2y"}, | |
| 258 | + {0x0ef1fa10, 0x0fffffff, "fmstat%c"}, | |
| 259 | + {0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"}, | |
| 260 | + {0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"}, | |
| 261 | + {0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"}, | |
| 262 | + {0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"}, | |
| 263 | + {0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"}, | |
| 264 | + {0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def 0x%16-19x>"}, | |
| 265 | + {0x0e100b00, 0x0ff00ff0, "fmscd%c\t%1z, %2z, %0z"}, | |
| 266 | + {0x0e100a00, 0x0fb00f50, "fmscs%c\t%1y, %2y, %0y"}, | |
| 267 | + {0x0e000a10, 0x0ff00f7f, "fmsr%c\t%2y, %12-15r"}, | |
| 268 | + {0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%12-15r, %16-19r, %4y"}, | |
| 269 | + {0x0e200b00, 0x0ff00ff0, "fmuld%c\t%1z, %2z, %0z"}, | |
| 270 | + {0x0e200a00, 0x0fb00f50, "fmuls%c\t%1y, %2y, %0y"}, | |
| 271 | + {0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"}, | |
| 272 | + {0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"}, | |
| 273 | + {0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"}, | |
| 274 | + {0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"}, | |
| 275 | + {0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"}, | |
| 276 | + {0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def 0x%16-19x>, %12-15r"}, | |
| 277 | + {0x0eb10b40, 0x0fff0ff0, "fnegd%c\t%1z, %0z"}, | |
| 278 | + {0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%1y, %0y"}, | |
| 279 | + {0x0e000b40, 0x0ff00ff0, "fnmacd%c\t%1z, %2z, %0z"}, | |
| 280 | + {0x0e000a40, 0x0fb00f50, "fnmacs%c\t%1y, %2y, %0y"}, | |
| 281 | + {0x0e100b40, 0x0ff00ff0, "fnmscd%c\t%1z, %2z, %0z"}, | |
| 282 | + {0x0e100a40, 0x0fb00f50, "fnmscs%c\t%1y, %2y, %0y"}, | |
| 283 | + {0x0e200b40, 0x0ff00ff0, "fnmuld%c\t%1z, %2z, %0z"}, | |
| 284 | + {0x0e200a40, 0x0fb00f50, "fnmuls%c\t%1y, %2y, %0y"}, | |
| 285 | + {0x0eb80bc0, 0x0fff0fd0, "fsitod%c\t%1z, %0y"}, | |
| 286 | + {0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%1y, %0y"}, | |
| 287 | + {0x0eb10bc0, 0x0fff0ff0, "fsqrtd%c\t%1z, %0z"}, | |
| 288 | + {0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%1y, %0y"}, | |
| 289 | + {0x0d000b00, 0x0f700f00, "fstd%c\t%1z, %A"}, | |
| 290 | + {0x0c800b00, 0x0fd00f00, "fstmia%0?xd%c\t%16-19r%21'!, %3z"}, | |
| 291 | + {0x0d200b00, 0x0ff00f00, "fstmdb%0?xd%c\t%16-19r!, %3z"}, | |
| 292 | + {0x0d000a00, 0x0f300f00, "fsts%c\t%1y, %A"}, | |
| 293 | + {0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %3y"}, | |
| 294 | + {0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %3y"}, | |
| 295 | + {0x0e300b40, 0x0ff00ff0, "fsubd%c\t%1z, %2z, %0z"}, | |
| 296 | + {0x0e300a40, 0x0fb00f50, "fsubs%c\t%1y, %2y, %0y"}, | |
| 297 | + {0x0ebc0b40, 0x0fbe0f70, "fto%16?sui%7'zd%c\t%1y, %0z"}, | |
| 298 | + {0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%1y, %0y"}, | |
| 299 | + {0x0eb80b40, 0x0fff0fd0, "fuitod%c\t%1z, %0y"}, | |
| 300 | + {0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%1y, %0y"}, | |
| 301 | + | |
| 302 | + /* Cirrus coprocessor instructions. */ | |
| 303 | + {0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"}, | |
| 304 | + {0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"}, | |
| 305 | + {0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"}, | |
| 306 | + {0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"}, | |
| 307 | + {0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"}, | |
| 308 | + {0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"}, | |
| 309 | + {0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"}, | |
| 310 | + {0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"}, | |
| 311 | + {0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"}, | |
| 312 | + {0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"}, | |
| 313 | + {0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"}, | |
| 314 | + {0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"}, | |
| 315 | + {0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"}, | |
| 316 | + {0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"}, | |
| 317 | + {0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"}, | |
| 318 | + {0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"}, | |
| 319 | + {0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"}, | |
| 320 | + {0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"}, | |
| 321 | + {0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"}, | |
| 322 | + {0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"}, | |
| 323 | + {0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"}, | |
| 324 | + {0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"}, | |
| 325 | + {0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"}, | |
| 326 | + {0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"}, | |
| 327 | + {0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"}, | |
| 328 | + {0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"}, | |
| 329 | + {0x0e100610, 0x0ff0fff0, "cfmval32%c\tmvax%0-3d, mvfx%16-19d"}, | |
| 330 | + {0x0e000610, 0x0ff0fff0, "cfmv32al%c\tmvfx%0-3d, mvax%16-19d"}, | |
| 331 | + {0x0e100630, 0x0ff0fff0, "cfmvam32%c\tmvax%0-3d, mvfx%16-19d"}, | |
| 332 | + {0x0e000630, 0x0ff0fff0, "cfmv32am%c\tmvfx%0-3d, mvax%16-19d"}, | |
| 333 | + {0x0e100650, 0x0ff0fff0, "cfmvah32%c\tmvax%0-3d, mvfx%16-19d"}, | |
| 334 | + {0x0e000650, 0x0ff0fff0, "cfmv32ah%c\tmvfx%0-3d, mvax%16-19d"}, | |
| 335 | + {0x0e000670, 0x0ff0fff0, "cfmv32a%c\tmvfx%0-3d, mvax%16-19d"}, | |
| 336 | + {0x0e100670, 0x0ff0fff0, "cfmva32%c\tmvax%0-3d, mvfx%16-19d"}, | |
| 337 | + {0x0e000690, 0x0ff0fff0, "cfmv64a%c\tmvdx%0-3d, mvax%16-19d"}, | |
| 338 | + {0x0e100690, 0x0ff0fff0, "cfmva64%c\tmvax%0-3d, mvdx%16-19d"}, | |
| 339 | + {0x0e1006b0, 0x0ff0fff0, "cfmvsc32%c\tdspsc, mvfx%16-19d"}, | |
| 340 | + {0x0e0006b0, 0x0ff0fff0, "cfmv32sc%c\tmvfx%0-3d, dspsc"}, | |
| 341 | + {0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"}, | |
| 342 | + {0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"}, | |
| 343 | + {0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"}, | |
| 344 | + {0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"}, | |
| 345 | + {0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"}, | |
| 346 | + {0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"}, | |
| 347 | + {0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"}, | |
| 348 | + {0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"}, | |
| 349 | + {0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"}, | |
| 350 | + {0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"}, | |
| 351 | + {0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"}, | |
| 352 | + {0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"}, | |
| 353 | + {0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"}, | |
| 354 | + {0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"}, | |
| 355 | + {0x0e000500, 0x0ff00f00, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"}, | |
| 356 | + {0x0e200500, 0x0ff00f00, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"}, | |
| 357 | + {0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"}, | |
| 358 | + {0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"}, | |
| 359 | + {0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"}, | |
| 360 | + {0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"}, | |
| 361 | + {0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"}, | |
| 362 | + {0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"}, | |
| 363 | + {0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"}, | |
| 364 | + {0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"}, | |
| 365 | + {0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"}, | |
| 366 | + {0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"}, | |
| 367 | + {0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"}, | |
| 368 | + {0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"}, | |
| 369 | + {0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"}, | |
| 370 | + {0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"}, | |
| 371 | + {0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"}, | |
| 372 | + {0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"}, | |
| 373 | + {0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"}, | |
| 374 | + {0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"}, | |
| 375 | + {0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, | |
| 376 | + {0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"}, | |
| 377 | + {0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, | |
| 378 | + {0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"}, | |
| 379 | + {0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, | |
| 380 | + {0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"}, | |
| 381 | + {0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, | |
| 382 | + {0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, | |
| 383 | + {0x0e000600, 0x0ff00f00, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, | |
| 384 | + {0x0e100600, 0x0ff00f00, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, | |
| 385 | + {0x0e200600, 0x0ff00f00, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"}, | |
| 386 | + {0x0e300600, 0x0ff00f00, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"}, | |
| 387 | + | |
| 388 | + /* Generic coprocessor instructions */ | |
| 389 | + {0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"}, | |
| 390 | + {0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, | |
| 391 | + {0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, | |
| 392 | + {0x0c000000, 0x0e100000, "stc%c%22'l\t%8-11d, cr%12-15d, %A"}, | |
| 393 | + {0x0c100000, 0x0e100000, "ldc%c%22'l\t%8-11d, cr%12-15d, %A"}, | |
| 394 | + | |
| 395 | + /* The rest. */ | |
| 396 | + {0x00000000, 0x00000000, "undefined instruction %0-31x"}, | |
| 397 | + {0x00000000, 0x00000000, 0} | |
| 398 | +}; | |
| 399 | + | |
| 400 | +#define BDISP(x) ((((x) & 0xffffff) ^ 0x800000) - 0x800000) /* 26 bit */ | |
| 401 | + | |
| 402 | +static struct thumb_opcode thumb_opcodes[] = | |
| 403 | +{ | |
| 404 | + /* Thumb instructions. */ | |
| 405 | + | |
| 406 | + /* ARM V5 ISA extends Thumb. */ | |
| 407 | + {0xbe00, 0xff00, "bkpt\t%0-7x"}, | |
| 408 | + {0x4780, 0xff87, "blx\t%3-6r"}, /* note: 4 bit register number. */ | |
| 409 | + /* Note: this is BLX(2). BLX(1) is done in arm-dis.c/print_insn_thumb() | |
| 410 | + as an extension of the special processing there for Thumb BL. | |
| 411 | + BL and BLX(1) involve 2 successive 16-bit instructions, which must | |
| 412 | + always appear together in the correct order. So, the empty | |
| 413 | + string is put in this table, and the string interpreter takes <empty> | |
| 414 | + to mean it has a pair of BL-ish instructions. */ | |
| 415 | + {0x46C0, 0xFFFF, "nop\t\t\t(mov r8, r8)"}, | |
| 416 | + /* Format 5 instructions do not update the PSR. */ | |
| 417 | + {0x1C00, 0xFFC0, "mov\t%0-2r, %3-5r\t\t(add %0-2r, %3-5r, #%6-8d)"}, | |
| 418 | + /* Format 4. */ | |
| 419 | + {0x4000, 0xFFC0, "and\t%0-2r, %3-5r"}, | |
| 420 | + {0x4040, 0xFFC0, "eor\t%0-2r, %3-5r"}, | |
| 421 | + {0x4080, 0xFFC0, "lsl\t%0-2r, %3-5r"}, | |
| 422 | + {0x40C0, 0xFFC0, "lsr\t%0-2r, %3-5r"}, | |
| 423 | + {0x4100, 0xFFC0, "asr\t%0-2r, %3-5r"}, | |
| 424 | + {0x4140, 0xFFC0, "adc\t%0-2r, %3-5r"}, | |
| 425 | + {0x4180, 0xFFC0, "sbc\t%0-2r, %3-5r"}, | |
| 426 | + {0x41C0, 0xFFC0, "ror\t%0-2r, %3-5r"}, | |
| 427 | + {0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"}, | |
| 428 | + {0x4240, 0xFFC0, "neg\t%0-2r, %3-5r"}, | |
| 429 | + {0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"}, | |
| 430 | + {0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"}, | |
| 431 | + {0x4300, 0xFFC0, "orr\t%0-2r, %3-5r"}, | |
| 432 | + {0x4340, 0xFFC0, "mul\t%0-2r, %3-5r"}, | |
| 433 | + {0x4380, 0xFFC0, "bic\t%0-2r, %3-5r"}, | |
| 434 | + {0x43C0, 0xFFC0, "mvn\t%0-2r, %3-5r"}, | |
| 435 | + /* format 13 */ | |
| 436 | + {0xB000, 0xFF80, "add\tsp, #%0-6W"}, | |
| 437 | + {0xB080, 0xFF80, "sub\tsp, #%0-6W"}, | |
| 438 | + /* format 5 */ | |
| 439 | + {0x4700, 0xFF80, "bx\t%S"}, | |
| 440 | + {0x4400, 0xFF00, "add\t%D, %S"}, | |
| 441 | + {0x4500, 0xFF00, "cmp\t%D, %S"}, | |
| 442 | + {0x4600, 0xFF00, "mov\t%D, %S"}, | |
| 443 | + /* format 14 */ | |
| 444 | + {0xB400, 0xFE00, "push\t%N"}, | |
| 445 | + {0xBC00, 0xFE00, "pop\t%O"}, | |
| 446 | + /* format 2 */ | |
| 447 | + {0x1800, 0xFE00, "add\t%0-2r, %3-5r, %6-8r"}, | |
| 448 | + {0x1A00, 0xFE00, "sub\t%0-2r, %3-5r, %6-8r"}, | |
| 449 | + {0x1C00, 0xFE00, "add\t%0-2r, %3-5r, #%6-8d"}, | |
| 450 | + {0x1E00, 0xFE00, "sub\t%0-2r, %3-5r, #%6-8d"}, | |
| 451 | + /* format 8 */ | |
| 452 | + {0x5200, 0xFE00, "strh\t%0-2r, [%3-5r, %6-8r]"}, | |
| 453 | + {0x5A00, 0xFE00, "ldrh\t%0-2r, [%3-5r, %6-8r]"}, | |
| 454 | + {0x5600, 0xF600, "ldrs%11?hb\t%0-2r, [%3-5r, %6-8r]"}, | |
| 455 | + /* format 7 */ | |
| 456 | + {0x5000, 0xFA00, "str%10'b\t%0-2r, [%3-5r, %6-8r]"}, | |
| 457 | + {0x5800, 0xFA00, "ldr%10'b\t%0-2r, [%3-5r, %6-8r]"}, | |
| 458 | + /* format 1 */ | |
| 459 | + {0x0000, 0xF800, "lsl\t%0-2r, %3-5r, #%6-10d"}, | |
| 460 | + {0x0800, 0xF800, "lsr\t%0-2r, %3-5r, #%6-10d"}, | |
| 461 | + {0x1000, 0xF800, "asr\t%0-2r, %3-5r, #%6-10d"}, | |
| 462 | + /* format 3 */ | |
| 463 | + {0x2000, 0xF800, "mov\t%8-10r, #%0-7d"}, | |
| 464 | + {0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"}, | |
| 465 | + {0x3000, 0xF800, "add\t%8-10r, #%0-7d"}, | |
| 466 | + {0x3800, 0xF800, "sub\t%8-10r, #%0-7d"}, | |
| 467 | + /* format 6 */ | |
| 468 | + {0x4800, 0xF800, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */ | |
| 469 | + /* format 9 */ | |
| 470 | + {0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"}, | |
| 471 | + {0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"}, | |
| 472 | + {0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"}, | |
| 473 | + {0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"}, | |
| 474 | + /* format 10 */ | |
| 475 | + {0x8000, 0xF800, "strh\t%0-2r, [%3-5r, #%6-10H]"}, | |
| 476 | + {0x8800, 0xF800, "ldrh\t%0-2r, [%3-5r, #%6-10H]"}, | |
| 477 | + /* format 11 */ | |
| 478 | + {0x9000, 0xF800, "str\t%8-10r, [sp, #%0-7W]"}, | |
| 479 | + {0x9800, 0xF800, "ldr\t%8-10r, [sp, #%0-7W]"}, | |
| 480 | + /* format 12 */ | |
| 481 | + {0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"}, | |
| 482 | + {0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"}, | |
| 483 | + /* format 15 */ | |
| 484 | + {0xC000, 0xF800, "stmia\t%8-10r!,%M"}, | |
| 485 | + {0xC800, 0xF800, "ldmia\t%8-10r!,%M"}, | |
| 486 | + /* format 18 */ | |
| 487 | + {0xE000, 0xF800, "b\t%0-10B"}, | |
| 488 | + {0xE800, 0xF800, "undefined"}, | |
| 489 | + /* format 19 */ | |
| 490 | + {0xF000, 0xF800, ""}, /* special processing required in disassembler */ | |
| 491 | + {0xF800, 0xF800, "second half of BL instruction %0-15x"}, | |
| 492 | + /* format 16 */ | |
| 493 | + {0xD000, 0xFF00, "beq\t%0-7B"}, | |
| 494 | + {0xD100, 0xFF00, "bne\t%0-7B"}, | |
| 495 | + {0xD200, 0xFF00, "bcs\t%0-7B"}, | |
| 496 | + {0xD300, 0xFF00, "bcc\t%0-7B"}, | |
| 497 | + {0xD400, 0xFF00, "bmi\t%0-7B"}, | |
| 498 | + {0xD500, 0xFF00, "bpl\t%0-7B"}, | |
| 499 | + {0xD600, 0xFF00, "bvs\t%0-7B"}, | |
| 500 | + {0xD700, 0xFF00, "bvc\t%0-7B"}, | |
| 501 | + {0xD800, 0xFF00, "bhi\t%0-7B"}, | |
| 502 | + {0xD900, 0xFF00, "bls\t%0-7B"}, | |
| 503 | + {0xDA00, 0xFF00, "bge\t%0-7B"}, | |
| 504 | + {0xDB00, 0xFF00, "blt\t%0-7B"}, | |
| 505 | + {0xDC00, 0xFF00, "bgt\t%0-7B"}, | |
| 506 | + {0xDD00, 0xFF00, "ble\t%0-7B"}, | |
| 507 | + /* format 17 */ | |
| 508 | + {0xDE00, 0xFF00, "bal\t%0-7B"}, | |
| 509 | + {0xDF00, 0xFF00, "swi\t%0-7d"}, | |
| 510 | + /* format 9 */ | |
| 511 | + {0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"}, | |
| 512 | + {0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"}, | |
| 513 | + {0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"}, | |
| 514 | + {0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"}, | |
| 515 | + /* the rest */ | |
| 516 | + {0x0000, 0x0000, "undefined instruction %0-15x"}, | |
| 517 | + {0x0000, 0x0000, 0} | |
| 518 | +}; | |
| 519 | + | |
| 520 | +#define BDISP23(x) ((((((x) & 0x07ff) << 11) | (((x) & 0x07ff0000) >> 16)) \ | |
| 521 | + ^ 0x200000) - 0x200000) /* 23bit */ | |
| 522 | + | |
| 523 | +#ifndef streq | |
| 524 | +#define streq(a,b) (strcmp ((a), (b)) == 0) | |
| 525 | +#endif | |
| 526 | + | |
| 527 | +#ifndef strneq | |
| 528 | +#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0) | |
| 529 | +#endif | |
| 530 | + | |
| 531 | +#ifndef NUM_ELEM | |
| 532 | +#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0]) | |
| 533 | +#endif | |
| 534 | + | |
| 535 | +static char * arm_conditional[] = | |
| 536 | +{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", | |
| 537 | + "hi", "ls", "ge", "lt", "gt", "le", "", "nv"}; | |
| 538 | + | |
| 539 | +typedef struct | |
| 540 | +{ | |
| 541 | + const char * name; | |
| 542 | + const char * description; | |
| 543 | + const char * reg_names[16]; | |
| 544 | +} | |
| 545 | +arm_regname; | |
| 546 | + | |
| 547 | +static arm_regname regnames[] = | |
| 548 | +{ | |
| 549 | + { "raw" , "Select raw register names", | |
| 550 | + { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}}, | |
| 551 | + { "gcc", "Select register names used by GCC", | |
| 552 | + { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }}, | |
| 553 | + { "std", "Select register names used in ARM's ISA documentation", | |
| 554 | + { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }}, | |
| 555 | + { "apcs", "Select register names used in the APCS", | |
| 556 | + { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }}, | |
| 557 | + { "atpcs", "Select register names used in the ATPCS", | |
| 558 | + { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }}, | |
| 559 | + { "special-atpcs", "Select special register names used in the ATPCS", | |
| 560 | + { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }} | |
| 561 | +}; | |
| 562 | + | |
| 563 | +/* Default to GCC register name set. */ | |
| 564 | +static unsigned int regname_selected = 1; | |
| 565 | + | |
| 566 | +#define NUM_ARM_REGNAMES NUM_ELEM (regnames) | |
| 567 | +#define arm_regnames regnames[regname_selected].reg_names | |
| 568 | + | |
| 569 | +static boolean force_thumb = false; | |
| 570 | + | |
| 571 | +static char * arm_fp_const[] = | |
| 572 | +{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"}; | |
| 573 | + | |
| 574 | +static char * arm_shift[] = | |
| 575 | +{"lsl", "lsr", "asr", "ror"}; | |
| 576 | + | |
| 577 | +/* Forward declarations. */ | |
| 578 | +static void arm_decode_shift PARAMS ((long, fprintf_ftype, void *)); | |
| 579 | +static int print_insn_arm1 PARAMS ((bfd_vma, struct disassemble_info *, long)); | |
| 580 | +static int print_insn_thumb PARAMS ((bfd_vma, struct disassemble_info *, long)); | |
| 581 | +static void parse_disassembler_options PARAMS ((char *)); | |
| 582 | +int get_arm_regname_num_options (void); | |
| 583 | +int set_arm_regname_option (int option); | |
| 584 | +int get_arm_regnames (int option, const char **setname, | |
| 585 | + const char **setdescription, | |
| 586 | + const char ***register_names); | |
| 587 | + | |
| 588 | +/* Functions. */ | |
| 589 | +int | |
| 590 | +get_arm_regname_num_options () | |
| 591 | +{ | |
| 592 | + return NUM_ARM_REGNAMES; | |
| 593 | +} | |
| 594 | + | |
| 595 | +int | |
| 596 | +set_arm_regname_option (option) | |
| 597 | + int option; | |
| 598 | +{ | |
| 599 | + int old = regname_selected; | |
| 600 | + regname_selected = option; | |
| 601 | + return old; | |
| 602 | +} | |
| 603 | + | |
| 604 | +int | |
| 605 | +get_arm_regnames (option, setname, setdescription, register_names) | |
| 606 | + int option; | |
| 607 | + const char **setname; | |
| 608 | + const char **setdescription; | |
| 609 | + const char ***register_names; | |
| 610 | +{ | |
| 611 | + *setname = regnames[option].name; | |
| 612 | + *setdescription = regnames[option].description; | |
| 613 | + *register_names = regnames[option].reg_names; | |
| 614 | + return 16; | |
| 615 | +} | |
| 616 | + | |
| 617 | +static void | |
| 618 | +arm_decode_shift (given, func, stream) | |
| 619 | + long given; | |
| 620 | + fprintf_ftype func; | |
| 621 | + void * stream; | |
| 622 | +{ | |
| 623 | + func (stream, "%s", arm_regnames[given & 0xf]); | |
| 624 | + | |
| 625 | + if ((given & 0xff0) != 0) | |
| 626 | + { | |
| 627 | + if ((given & 0x10) == 0) | |
| 628 | + { | |
| 629 | + int amount = (given & 0xf80) >> 7; | |
| 630 | + int shift = (given & 0x60) >> 5; | |
| 631 | + | |
| 632 | + if (amount == 0) | |
| 633 | + { | |
| 634 | + if (shift == 3) | |
| 635 | + { | |
| 636 | + func (stream, ", rrx"); | |
| 637 | + return; | |
| 638 | + } | |
| 639 | + | |
| 640 | + amount = 32; | |
| 641 | + } | |
| 642 | + | |
| 643 | + func (stream, ", %s #%d", arm_shift[shift], amount); | |
| 644 | + } | |
| 645 | + else | |
| 646 | + func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5], | |
| 647 | + arm_regnames[(given & 0xf00) >> 8]); | |
| 648 | + } | |
| 649 | +} | |
| 650 | + | |
| 651 | +/* Print one instruction from PC on INFO->STREAM. | |
| 652 | + Return the size of the instruction (always 4 on ARM). */ | |
| 653 | + | |
| 654 | +static int | |
| 655 | +print_insn_arm1 (pc, info, given) | |
| 656 | + bfd_vma pc; | |
| 657 | + struct disassemble_info * info; | |
| 658 | + long given; | |
| 659 | +{ | |
| 660 | + struct arm_opcode * insn; | |
| 661 | + void * stream = info->stream; | |
| 662 | + fprintf_ftype func = info->fprintf_func; | |
| 663 | + | |
| 664 | + for (insn = arm_opcodes; insn->assembler; insn++) | |
| 665 | + { | |
| 666 | + if ((given & insn->mask) == insn->value) | |
| 667 | + { | |
| 668 | + char * c; | |
| 669 | + | |
| 670 | + for (c = insn->assembler; *c; c++) | |
| 671 | + { | |
| 672 | + if (*c == '%') | |
| 673 | + { | |
| 674 | + switch (*++c) | |
| 675 | + { | |
| 676 | + case '%': | |
| 677 | + func (stream, "%%"); | |
| 678 | + break; | |
| 679 | + | |
| 680 | + case 'a': | |
| 681 | + if (((given & 0x000f0000) == 0x000f0000) | |
| 682 | + && ((given & 0x02000000) == 0)) | |
| 683 | + { | |
| 684 | + int offset = given & 0xfff; | |
| 685 | + | |
| 686 | + func (stream, "[pc"); | |
| 687 | + | |
| 688 | + if (given & 0x01000000) | |
| 689 | + { | |
| 690 | + if ((given & 0x00800000) == 0) | |
| 691 | + offset = - offset; | |
| 692 | + | |
| 693 | + /* Pre-indexed. */ | |
| 694 | + func (stream, ", #%d]", offset); | |
| 695 | + | |
| 696 | + offset += pc + 8; | |
| 697 | + | |
| 698 | + /* Cope with the possibility of write-back | |
| 699 | + being used. Probably a very dangerous thing | |
| 700 | + for the programmer to do, but who are we to | |
| 701 | + argue ? */ | |
| 702 | + if (given & 0x00200000) | |
| 703 | + func (stream, "!"); | |
| 704 | + } | |
| 705 | + else | |
| 706 | + { | |
| 707 | + /* Post indexed. */ | |
| 708 | + func (stream, "], #%d", offset); | |
| 709 | + | |
| 710 | + /* ie ignore the offset. */ | |
| 711 | + offset = pc + 8; | |
| 712 | + } | |
| 713 | + | |
| 714 | + func (stream, "\t; "); | |
| 715 | + info->print_address_func (offset, info); | |
| 716 | + } | |
| 717 | + else | |
| 718 | + { | |
| 719 | + func (stream, "[%s", | |
| 720 | + arm_regnames[(given >> 16) & 0xf]); | |
| 721 | + if ((given & 0x01000000) != 0) | |
| 722 | + { | |
| 723 | + if ((given & 0x02000000) == 0) | |
| 724 | + { | |
| 725 | + int offset = given & 0xfff; | |
| 726 | + if (offset) | |
| 727 | + func (stream, ", %s#%d", | |
| 728 | + (((given & 0x00800000) == 0) | |
| 729 | + ? "-" : ""), offset); | |
| 730 | + } | |
| 731 | + else | |
| 732 | + { | |
| 733 | + func (stream, ", %s", | |
| 734 | + (((given & 0x00800000) == 0) | |
| 735 | + ? "-" : "")); | |
| 736 | + arm_decode_shift (given, func, stream); | |
| 737 | + } | |
| 738 | + | |
| 739 | + func (stream, "]%s", | |
| 740 | + ((given & 0x00200000) != 0) ? "!" : ""); | |
| 741 | + } | |
| 742 | + else | |
| 743 | + { | |
| 744 | + if ((given & 0x02000000) == 0) | |
| 745 | + { | |
| 746 | + int offset = given & 0xfff; | |
| 747 | + if (offset) | |
| 748 | + func (stream, "], %s#%d", | |
| 749 | + (((given & 0x00800000) == 0) | |
| 750 | + ? "-" : ""), offset); | |
| 751 | + else | |
| 752 | + func (stream, "]"); | |
| 753 | + } | |
| 754 | + else | |
| 755 | + { | |
| 756 | + func (stream, "], %s", | |
| 757 | + (((given & 0x00800000) == 0) | |
| 758 | + ? "-" : "")); | |
| 759 | + arm_decode_shift (given, func, stream); | |
| 760 | + } | |
| 761 | + } | |
| 762 | + } | |
| 763 | + break; | |
| 764 | + | |
| 765 | + case 's': | |
| 766 | + if ((given & 0x004f0000) == 0x004f0000) | |
| 767 | + { | |
| 768 | + /* PC relative with immediate offset. */ | |
| 769 | + int offset = ((given & 0xf00) >> 4) | (given & 0xf); | |
| 770 | + | |
| 771 | + if ((given & 0x00800000) == 0) | |
| 772 | + offset = -offset; | |
| 773 | + | |
| 774 | + func (stream, "[pc, #%d]\t; ", offset); | |
| 775 | + | |
| 776 | + (*info->print_address_func) | |
| 777 | + (offset + pc + 8, info); | |
| 778 | + } | |
| 779 | + else | |
| 780 | + { | |
| 781 | + func (stream, "[%s", | |
| 782 | + arm_regnames[(given >> 16) & 0xf]); | |
| 783 | + if ((given & 0x01000000) != 0) | |
| 784 | + { | |
| 785 | + /* Pre-indexed. */ | |
| 786 | + if ((given & 0x00400000) == 0x00400000) | |
| 787 | + { | |
| 788 | + /* Immediate. */ | |
| 789 | + int offset = ((given & 0xf00) >> 4) | (given & 0xf); | |
| 790 | + if (offset) | |
| 791 | + func (stream, ", %s#%d", | |
| 792 | + (((given & 0x00800000) == 0) | |
| 793 | + ? "-" : ""), offset); | |
| 794 | + } | |
| 795 | + else | |
| 796 | + { | |
| 797 | + /* Register. */ | |
| 798 | + func (stream, ", %s%s", | |
| 799 | + (((given & 0x00800000) == 0) | |
| 800 | + ? "-" : ""), | |
| 801 | + arm_regnames[given & 0xf]); | |
| 802 | + } | |
| 803 | + | |
| 804 | + func (stream, "]%s", | |
| 805 | + ((given & 0x00200000) != 0) ? "!" : ""); | |
| 806 | + } | |
| 807 | + else | |
| 808 | + { | |
| 809 | + /* Post-indexed. */ | |
| 810 | + if ((given & 0x00400000) == 0x00400000) | |
| 811 | + { | |
| 812 | + /* Immediate. */ | |
| 813 | + int offset = ((given & 0xf00) >> 4) | (given & 0xf); | |
| 814 | + if (offset) | |
| 815 | + func (stream, "], %s#%d", | |
| 816 | + (((given & 0x00800000) == 0) | |
| 817 | + ? "-" : ""), offset); | |
| 818 | + else | |
| 819 | + func (stream, "]"); | |
| 820 | + } | |
| 821 | + else | |
| 822 | + { | |
| 823 | + /* Register. */ | |
| 824 | + func (stream, "], %s%s", | |
| 825 | + (((given & 0x00800000) == 0) | |
| 826 | + ? "-" : ""), | |
| 827 | + arm_regnames[given & 0xf]); | |
| 828 | + } | |
| 829 | + } | |
| 830 | + } | |
| 831 | + break; | |
| 832 | + | |
| 833 | + case 'b': | |
| 834 | + (*info->print_address_func) | |
| 835 | + (BDISP (given) * 4 + pc + 8, info); | |
| 836 | + break; | |
| 837 | + | |
| 838 | + case 'c': | |
| 839 | + func (stream, "%s", | |
| 840 | + arm_conditional [(given >> 28) & 0xf]); | |
| 841 | + break; | |
| 842 | + | |
| 843 | + case 'm': | |
| 844 | + { | |
| 845 | + int started = 0; | |
| 846 | + int reg; | |
| 847 | + | |
| 848 | + func (stream, "{"); | |
| 849 | + for (reg = 0; reg < 16; reg++) | |
| 850 | + if ((given & (1 << reg)) != 0) | |
| 851 | + { | |
| 852 | + if (started) | |
| 853 | + func (stream, ", "); | |
| 854 | + started = 1; | |
| 855 | + func (stream, "%s", arm_regnames[reg]); | |
| 856 | + } | |
| 857 | + func (stream, "}"); | |
| 858 | + } | |
| 859 | + break; | |
| 860 | + | |
| 861 | + case 'o': | |
| 862 | + if ((given & 0x02000000) != 0) | |
| 863 | + { | |
| 864 | + int rotate = (given & 0xf00) >> 7; | |
| 865 | + int immed = (given & 0xff); | |
| 866 | + immed = (((immed << (32 - rotate)) | |
| 867 | + | (immed >> rotate)) & 0xffffffff); | |
| 868 | + func (stream, "#%d\t; 0x%x", immed, immed); | |
| 869 | + } | |
| 870 | + else | |
| 871 | + arm_decode_shift (given, func, stream); | |
| 872 | + break; | |
| 873 | + | |
| 874 | + case 'p': | |
| 875 | + if ((given & 0x0000f000) == 0x0000f000) | |
| 876 | + func (stream, "p"); | |
| 877 | + break; | |
| 878 | + | |
| 879 | + case 't': | |
| 880 | + if ((given & 0x01200000) == 0x00200000) | |
| 881 | + func (stream, "t"); | |
| 882 | + break; | |
| 883 | + | |
| 884 | + case 'A': | |
| 885 | + func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]); | |
| 886 | + if ((given & 0x01000000) != 0) | |
| 887 | + { | |
| 888 | + int offset = given & 0xff; | |
| 889 | + if (offset) | |
| 890 | + func (stream, ", %s#%d]%s", | |
| 891 | + ((given & 0x00800000) == 0 ? "-" : ""), | |
| 892 | + offset * 4, | |
| 893 | + ((given & 0x00200000) != 0 ? "!" : "")); | |
| 894 | + else | |
| 895 | + func (stream, "]"); | |
| 896 | + } | |
| 897 | + else | |
| 898 | + { | |
| 899 | + int offset = given & 0xff; | |
| 900 | + if (offset) | |
| 901 | + func (stream, "], %s#%d", | |
| 902 | + ((given & 0x00800000) == 0 ? "-" : ""), | |
| 903 | + offset * 4); | |
| 904 | + else | |
| 905 | + func (stream, "]"); | |
| 906 | + } | |
| 907 | + break; | |
| 908 | + | |
| 909 | + case 'B': | |
| 910 | + /* Print ARM V5 BLX(1) address: pc+25 bits. */ | |
| 911 | + { | |
| 912 | + bfd_vma address; | |
| 913 | + bfd_vma offset = 0; | |
| 914 | + | |
| 915 | + if (given & 0x00800000) | |
| 916 | + /* Is signed, hi bits should be ones. */ | |
| 917 | + offset = (-1) ^ 0x00ffffff; | |
| 918 | + | |
| 919 | + /* Offset is (SignExtend(offset field)<<2). */ | |
| 920 | + offset += given & 0x00ffffff; | |
| 921 | + offset <<= 2; | |
| 922 | + address = offset + pc + 8; | |
| 923 | + | |
| 924 | + if (given & 0x01000000) | |
| 925 | + /* H bit allows addressing to 2-byte boundaries. */ | |
| 926 | + address += 2; | |
| 927 | + | |
| 928 | + info->print_address_func (address, info); | |
| 929 | + } | |
| 930 | + break; | |
| 931 | + | |
| 932 | + case 'I': | |
| 933 | + /* Print a Cirrus/DSP shift immediate. */ | |
| 934 | + /* Immediates are 7bit signed ints with bits 0..3 in | |
| 935 | + bits 0..3 of opcode and bits 4..6 in bits 5..7 | |
| 936 | + of opcode. */ | |
| 937 | + { | |
| 938 | + int imm; | |
| 939 | + | |
| 940 | + imm = (given & 0xf) | ((given & 0xe0) >> 1); | |
| 941 | + | |
| 942 | + /* Is ``imm'' a negative number? */ | |
| 943 | + if (imm & 0x40) | |
| 944 | + imm |= (-1 << 7); | |
| 945 | + | |
| 946 | + func (stream, "%d", imm); | |
| 947 | + } | |
| 948 | + | |
| 949 | + break; | |
| 950 | + | |
| 951 | + case 'C': | |
| 952 | + func (stream, "_"); | |
| 953 | + if (given & 0x80000) | |
| 954 | + func (stream, "f"); | |
| 955 | + if (given & 0x40000) | |
| 956 | + func (stream, "s"); | |
| 957 | + if (given & 0x20000) | |
| 958 | + func (stream, "x"); | |
| 959 | + if (given & 0x10000) | |
| 960 | + func (stream, "c"); | |
| 961 | + break; | |
| 962 | + | |
| 963 | + case 'F': | |
| 964 | + switch (given & 0x00408000) | |
| 965 | + { | |
| 966 | + case 0: | |
| 967 | + func (stream, "4"); | |
| 968 | + break; | |
| 969 | + case 0x8000: | |
| 970 | + func (stream, "1"); | |
| 971 | + break; | |
| 972 | + case 0x00400000: | |
| 973 | + func (stream, "2"); | |
| 974 | + break; | |
| 975 | + default: | |
| 976 | + func (stream, "3"); | |
| 977 | + } | |
| 978 | + break; | |
| 979 | + | |
| 980 | + case 'P': | |
| 981 | + switch (given & 0x00080080) | |
| 982 | + { | |
| 983 | + case 0: | |
| 984 | + func (stream, "s"); | |
| 985 | + break; | |
| 986 | + case 0x80: | |
| 987 | + func (stream, "d"); | |
| 988 | + break; | |
| 989 | + case 0x00080000: | |
| 990 | + func (stream, "e"); | |
| 991 | + break; | |
| 992 | + default: | |
| 993 | + func (stream, _("<illegal precision>")); | |
| 994 | + break; | |
| 995 | + } | |
| 996 | + break; | |
| 997 | + case 'Q': | |
| 998 | + switch (given & 0x00408000) | |
| 999 | + { | |
| 1000 | + case 0: | |
| 1001 | + func (stream, "s"); | |
| 1002 | + break; | |
| 1003 | + case 0x8000: | |
| 1004 | + func (stream, "d"); | |
| 1005 | + break; | |
| 1006 | + case 0x00400000: | |
| 1007 | + func (stream, "e"); | |
| 1008 | + break; | |
| 1009 | + default: | |
| 1010 | + func (stream, "p"); | |
| 1011 | + break; | |
| 1012 | + } | |
| 1013 | + break; | |
| 1014 | + case 'R': | |
| 1015 | + switch (given & 0x60) | |
| 1016 | + { | |
| 1017 | + case 0: | |
| 1018 | + break; | |
| 1019 | + case 0x20: | |
| 1020 | + func (stream, "p"); | |
| 1021 | + break; | |
| 1022 | + case 0x40: | |
| 1023 | + func (stream, "m"); | |
| 1024 | + break; | |
| 1025 | + default: | |
| 1026 | + func (stream, "z"); | |
| 1027 | + break; | |
| 1028 | + } | |
| 1029 | + break; | |
| 1030 | + | |
| 1031 | + case '0': case '1': case '2': case '3': case '4': | |
| 1032 | + case '5': case '6': case '7': case '8': case '9': | |
| 1033 | + { | |
| 1034 | + int bitstart = *c++ - '0'; | |
| 1035 | + int bitend = 0; | |
| 1036 | + while (*c >= '0' && *c <= '9') | |
| 1037 | + bitstart = (bitstart * 10) + *c++ - '0'; | |
| 1038 | + | |
| 1039 | + switch (*c) | |
| 1040 | + { | |
| 1041 | + case '-': | |
| 1042 | + c++; | |
| 1043 | + | |
| 1044 | + while (*c >= '0' && *c <= '9') | |
| 1045 | + bitend = (bitend * 10) + *c++ - '0'; | |
| 1046 | + | |
| 1047 | + if (!bitend) | |
| 1048 | + abort (); | |
| 1049 | + | |
| 1050 | + switch (*c) | |
| 1051 | + { | |
| 1052 | + case 'r': | |
| 1053 | + { | |
| 1054 | + long reg; | |
| 1055 | + | |
| 1056 | + reg = given >> bitstart; | |
| 1057 | + reg &= (2 << (bitend - bitstart)) - 1; | |
| 1058 | + | |
| 1059 | + func (stream, "%s", arm_regnames[reg]); | |
| 1060 | + } | |
| 1061 | + break; | |
| 1062 | + case 'd': | |
| 1063 | + { | |
| 1064 | + long reg; | |
| 1065 | + | |
| 1066 | + reg = given >> bitstart; | |
| 1067 | + reg &= (2 << (bitend - bitstart)) - 1; | |
| 1068 | + | |
| 1069 | + func (stream, "%d", reg); | |
| 1070 | + } | |
| 1071 | + break; | |
| 1072 | + case 'x': | |
| 1073 | + { | |
| 1074 | + long reg; | |
| 1075 | + | |
| 1076 | + reg = given >> bitstart; | |
| 1077 | + reg &= (2 << (bitend - bitstart)) - 1; | |
| 1078 | + | |
| 1079 | + func (stream, "0x%08x", reg); | |
| 1080 | + | |
| 1081 | + /* Some SWI instructions have special | |
| 1082 | + meanings. */ | |
| 1083 | + if ((given & 0x0fffffff) == 0x0FF00000) | |
| 1084 | + func (stream, "\t; IMB"); | |
| 1085 | + else if ((given & 0x0fffffff) == 0x0FF00001) | |
| 1086 | + func (stream, "\t; IMBRange"); | |
| 1087 | + } | |
| 1088 | + break; | |
| 1089 | + case 'X': | |
| 1090 | + { | |
| 1091 | + long reg; | |
| 1092 | + | |
| 1093 | + reg = given >> bitstart; | |
| 1094 | + reg &= (2 << (bitend - bitstart)) - 1; | |
| 1095 | + | |
| 1096 | + func (stream, "%01x", reg & 0xf); | |
| 1097 | + } | |
| 1098 | + break; | |
| 1099 | + case 'f': | |
| 1100 | + { | |
| 1101 | + long reg; | |
| 1102 | + | |
| 1103 | + reg = given >> bitstart; | |
| 1104 | + reg &= (2 << (bitend - bitstart)) - 1; | |
| 1105 | + | |
| 1106 | + if (reg > 7) | |
| 1107 | + func (stream, "#%s", | |
| 1108 | + arm_fp_const[reg & 7]); | |
| 1109 | + else | |
| 1110 | + func (stream, "f%d", reg); | |
| 1111 | + } | |
| 1112 | + break; | |
| 1113 | + default: | |
| 1114 | + abort (); | |
| 1115 | + } | |
| 1116 | + break; | |
| 1117 | + | |
| 1118 | + case 'y': | |
| 1119 | + case 'z': | |
| 1120 | + { | |
| 1121 | + int single = *c == 'y'; | |
| 1122 | + int regno; | |
| 1123 | + | |
| 1124 | + switch (bitstart) | |
| 1125 | + { | |
| 1126 | + case 4: /* Sm pair */ | |
| 1127 | + func (stream, "{"); | |
| 1128 | + /* Fall through. */ | |
| 1129 | + case 0: /* Sm, Dm */ | |
| 1130 | + regno = given & 0x0000000f; | |
| 1131 | + if (single) | |
| 1132 | + { | |
| 1133 | + regno <<= 1; | |
| 1134 | + regno += (given >> 5) & 1; | |
| 1135 | + } | |
| 1136 | + break; | |
| 1137 | + | |
| 1138 | + case 1: /* Sd, Dd */ | |
| 1139 | + regno = (given >> 12) & 0x0000000f; | |
| 1140 | + if (single) | |
| 1141 | + { | |
| 1142 | + regno <<= 1; | |
| 1143 | + regno += (given >> 22) & 1; | |
| 1144 | + } | |
| 1145 | + break; | |
| 1146 | + | |
| 1147 | + case 2: /* Sn, Dn */ | |
| 1148 | + regno = (given >> 16) & 0x0000000f; | |
| 1149 | + if (single) | |
| 1150 | + { | |
| 1151 | + regno <<= 1; | |
| 1152 | + regno += (given >> 7) & 1; | |
| 1153 | + } | |
| 1154 | + break; | |
| 1155 | + | |
| 1156 | + case 3: /* List */ | |
| 1157 | + func (stream, "{"); | |
| 1158 | + regno = (given >> 12) & 0x0000000f; | |
| 1159 | + if (single) | |
| 1160 | + { | |
| 1161 | + regno <<= 1; | |
| 1162 | + regno += (given >> 22) & 1; | |
| 1163 | + } | |
| 1164 | + break; | |
| 1165 | + | |
| 1166 | + | |
| 1167 | + default: | |
| 1168 | + abort (); | |
| 1169 | + } | |
| 1170 | + | |
| 1171 | + func (stream, "%c%d", single ? 's' : 'd', regno); | |
| 1172 | + | |
| 1173 | + if (bitstart == 3) | |
| 1174 | + { | |
| 1175 | + int count = given & 0xff; | |
| 1176 | + | |
| 1177 | + if (single == 0) | |
| 1178 | + count >>= 1; | |
| 1179 | + | |
| 1180 | + if (--count) | |
| 1181 | + { | |
| 1182 | + func (stream, "-%c%d", | |
| 1183 | + single ? 's' : 'd', | |
| 1184 | + regno + count); | |
| 1185 | + } | |
| 1186 | + | |
| 1187 | + func (stream, "}"); | |
| 1188 | + } | |
| 1189 | + else if (bitstart == 4) | |
| 1190 | + func (stream, ", %c%d}", single ? 's' : 'd', | |
| 1191 | + regno + 1); | |
| 1192 | + | |
| 1193 | + break; | |
| 1194 | + } | |
| 1195 | + | |
| 1196 | + case '`': | |
| 1197 | + c++; | |
| 1198 | + if ((given & (1 << bitstart)) == 0) | |
| 1199 | + func (stream, "%c", *c); | |
| 1200 | + break; | |
| 1201 | + case '\'': | |
| 1202 | + c++; | |
| 1203 | + if ((given & (1 << bitstart)) != 0) | |
| 1204 | + func (stream, "%c", *c); | |
| 1205 | + break; | |
| 1206 | + case '?': | |
| 1207 | + ++c; | |
| 1208 | + if ((given & (1 << bitstart)) != 0) | |
| 1209 | + func (stream, "%c", *c++); | |
| 1210 | + else | |
| 1211 | + func (stream, "%c", *++c); | |
| 1212 | + break; | |
| 1213 | + default: | |
| 1214 | + abort (); | |
| 1215 | + } | |
| 1216 | + break; | |
| 1217 | + | |
| 1218 | + default: | |
| 1219 | + abort (); | |
| 1220 | + } | |
| 1221 | + } | |
| 1222 | + } | |
| 1223 | + else | |
| 1224 | + func (stream, "%c", *c); | |
| 1225 | + } | |
| 1226 | + return 4; | |
| 1227 | + } | |
| 1228 | + } | |
| 1229 | + abort (); | |
| 1230 | +} | |
| 1231 | + | |
| 1232 | +/* Print one instruction from PC on INFO->STREAM. | |
| 1233 | + Return the size of the instruction. */ | |
| 1234 | + | |
| 1235 | +static int | |
| 1236 | +print_insn_thumb (pc, info, given) | |
| 1237 | + bfd_vma pc; | |
| 1238 | + struct disassemble_info * info; | |
| 1239 | + long given; | |
| 1240 | +{ | |
| 1241 | + struct thumb_opcode * insn; | |
| 1242 | + void * stream = info->stream; | |
| 1243 | + fprintf_ftype func = info->fprintf_func; | |
| 1244 | + | |
| 1245 | + for (insn = thumb_opcodes; insn->assembler; insn++) | |
| 1246 | + { | |
| 1247 | + if ((given & insn->mask) == insn->value) | |
| 1248 | + { | |
| 1249 | + char * c = insn->assembler; | |
| 1250 | + | |
| 1251 | + /* Special processing for Thumb 2 instruction BL sequence: */ | |
| 1252 | + if (!*c) /* Check for empty (not NULL) assembler string. */ | |
| 1253 | + { | |
| 1254 | + long offset; | |
| 1255 | + | |
| 1256 | + info->bytes_per_chunk = 4; | |
| 1257 | + info->bytes_per_line = 4; | |
| 1258 | + | |
| 1259 | + offset = BDISP23 (given); | |
| 1260 | + offset = offset * 2 + pc + 4; | |
| 1261 | + | |
| 1262 | + if ((given & 0x10000000) == 0) | |
| 1263 | + { | |
| 1264 | + func (stream, "blx\t"); | |
| 1265 | + offset &= 0xfffffffc; | |
| 1266 | + } | |
| 1267 | + else | |
| 1268 | + func (stream, "bl\t"); | |
| 1269 | + | |
| 1270 | + info->print_address_func (offset, info); | |
| 1271 | + return 4; | |
| 1272 | + } | |
| 1273 | + else | |
| 1274 | + { | |
| 1275 | + info->bytes_per_chunk = 2; | |
| 1276 | + info->bytes_per_line = 4; | |
| 1277 | + | |
| 1278 | + given &= 0xffff; | |
| 1279 | + | |
| 1280 | + for (; *c; c++) | |
| 1281 | + { | |
| 1282 | + if (*c == '%') | |
| 1283 | + { | |
| 1284 | + int domaskpc = 0; | |
| 1285 | + int domasklr = 0; | |
| 1286 | + | |
| 1287 | + switch (*++c) | |
| 1288 | + { | |
| 1289 | + case '%': | |
| 1290 | + func (stream, "%%"); | |
| 1291 | + break; | |
| 1292 | + | |
| 1293 | + case 'S': | |
| 1294 | + { | |
| 1295 | + long reg; | |
| 1296 | + | |
| 1297 | + reg = (given >> 3) & 0x7; | |
| 1298 | + if (given & (1 << 6)) | |
| 1299 | + reg += 8; | |
| 1300 | + | |
| 1301 | + func (stream, "%s", arm_regnames[reg]); | |
| 1302 | + } | |
| 1303 | + break; | |
| 1304 | + | |
| 1305 | + case 'D': | |
| 1306 | + { | |
| 1307 | + long reg; | |
| 1308 | + | |
| 1309 | + reg = given & 0x7; | |
| 1310 | + if (given & (1 << 7)) | |
| 1311 | + reg += 8; | |
| 1312 | + | |
| 1313 | + func (stream, "%s", arm_regnames[reg]); | |
| 1314 | + } | |
| 1315 | + break; | |
| 1316 | + | |
| 1317 | + case 'T': | |
| 1318 | + func (stream, "%s", | |
| 1319 | + arm_conditional [(given >> 8) & 0xf]); | |
| 1320 | + break; | |
| 1321 | + | |
| 1322 | + case 'N': | |
| 1323 | + if (given & (1 << 8)) | |
| 1324 | + domasklr = 1; | |
| 1325 | + /* Fall through. */ | |
| 1326 | + case 'O': | |
| 1327 | + if (*c == 'O' && (given & (1 << 8))) | |
| 1328 | + domaskpc = 1; | |
| 1329 | + /* Fall through. */ | |
| 1330 | + case 'M': | |
| 1331 | + { | |
| 1332 | + int started = 0; | |
| 1333 | + int reg; | |
| 1334 | + | |
| 1335 | + func (stream, "{"); | |
| 1336 | + | |
| 1337 | + /* It would be nice if we could spot | |
| 1338 | + ranges, and generate the rS-rE format: */ | |
| 1339 | + for (reg = 0; (reg < 8); reg++) | |
| 1340 | + if ((given & (1 << reg)) != 0) | |
| 1341 | + { | |
| 1342 | + if (started) | |
| 1343 | + func (stream, ", "); | |
| 1344 | + started = 1; | |
| 1345 | + func (stream, "%s", arm_regnames[reg]); | |
| 1346 | + } | |
| 1347 | + | |
| 1348 | + if (domasklr) | |
| 1349 | + { | |
| 1350 | + if (started) | |
| 1351 | + func (stream, ", "); | |
| 1352 | + started = 1; | |
| 1353 | + func (stream, arm_regnames[14] /* "lr" */); | |
| 1354 | + } | |
| 1355 | + | |
| 1356 | + if (domaskpc) | |
| 1357 | + { | |
| 1358 | + if (started) | |
| 1359 | + func (stream, ", "); | |
| 1360 | + func (stream, arm_regnames[15] /* "pc" */); | |
| 1361 | + } | |
| 1362 | + | |
| 1363 | + func (stream, "}"); | |
| 1364 | + } | |
| 1365 | + break; | |
| 1366 | + | |
| 1367 | + | |
| 1368 | + case '0': case '1': case '2': case '3': case '4': | |
| 1369 | + case '5': case '6': case '7': case '8': case '9': | |
| 1370 | + { | |
| 1371 | + int bitstart = *c++ - '0'; | |
| 1372 | + int bitend = 0; | |
| 1373 | + | |
| 1374 | + while (*c >= '0' && *c <= '9') | |
| 1375 | + bitstart = (bitstart * 10) + *c++ - '0'; | |
| 1376 | + | |
| 1377 | + switch (*c) | |
| 1378 | + { | |
| 1379 | + case '-': | |
| 1380 | + { | |
| 1381 | + long reg; | |
| 1382 | + | |
| 1383 | + c++; | |
| 1384 | + while (*c >= '0' && *c <= '9') | |
| 1385 | + bitend = (bitend * 10) + *c++ - '0'; | |
| 1386 | + if (!bitend) | |
| 1387 | + abort (); | |
| 1388 | + reg = given >> bitstart; | |
| 1389 | + reg &= (2 << (bitend - bitstart)) - 1; | |
| 1390 | + switch (*c) | |
| 1391 | + { | |
| 1392 | + case 'r': | |
| 1393 | + func (stream, "%s", arm_regnames[reg]); | |
| 1394 | + break; | |
| 1395 | + | |
| 1396 | + case 'd': | |
| 1397 | + func (stream, "%d", reg); | |
| 1398 | + break; | |
| 1399 | + | |
| 1400 | + case 'H': | |
| 1401 | + func (stream, "%d", reg << 1); | |
| 1402 | + break; | |
| 1403 | + | |
| 1404 | + case 'W': | |
| 1405 | + func (stream, "%d", reg << 2); | |
| 1406 | + break; | |
| 1407 | + | |
| 1408 | + case 'a': | |
| 1409 | + /* PC-relative address -- the bottom two | |
| 1410 | + bits of the address are dropped | |
| 1411 | + before the calculation. */ | |
| 1412 | + info->print_address_func | |
| 1413 | + (((pc + 4) & ~3) + (reg << 2), info); | |
| 1414 | + break; | |
| 1415 | + | |
| 1416 | + case 'x': | |
| 1417 | + func (stream, "0x%04x", reg); | |
| 1418 | + break; | |
| 1419 | + | |
| 1420 | + case 'I': | |
| 1421 | + reg = ((reg ^ (1 << bitend)) - (1 << bitend)); | |
| 1422 | + func (stream, "%d", reg); | |
| 1423 | + break; | |
| 1424 | + | |
| 1425 | + case 'B': | |
| 1426 | + reg = ((reg ^ (1 << bitend)) - (1 << bitend)); | |
| 1427 | + (*info->print_address_func) | |
| 1428 | + (reg * 2 + pc + 4, info); | |
| 1429 | + break; | |
| 1430 | + | |
| 1431 | + default: | |
| 1432 | + abort (); | |
| 1433 | + } | |
| 1434 | + } | |
| 1435 | + break; | |
| 1436 | + | |
| 1437 | + case '\'': | |
| 1438 | + c++; | |
| 1439 | + if ((given & (1 << bitstart)) != 0) | |
| 1440 | + func (stream, "%c", *c); | |
| 1441 | + break; | |
| 1442 | + | |
| 1443 | + case '?': | |
| 1444 | + ++c; | |
| 1445 | + if ((given & (1 << bitstart)) != 0) | |
| 1446 | + func (stream, "%c", *c++); | |
| 1447 | + else | |
| 1448 | + func (stream, "%c", *++c); | |
| 1449 | + break; | |
| 1450 | + | |
| 1451 | + default: | |
| 1452 | + abort (); | |
| 1453 | + } | |
| 1454 | + } | |
| 1455 | + break; | |
| 1456 | + | |
| 1457 | + default: | |
| 1458 | + abort (); | |
| 1459 | + } | |
| 1460 | + } | |
| 1461 | + else | |
| 1462 | + func (stream, "%c", *c); | |
| 1463 | + } | |
| 1464 | + } | |
| 1465 | + return 2; | |
| 1466 | + } | |
| 1467 | + } | |
| 1468 | + | |
| 1469 | + /* No match. */ | |
| 1470 | + abort (); | |
| 1471 | +} | |
| 1472 | + | |
| 1473 | +/* Parse an individual disassembler option. */ | |
| 1474 | + | |
| 1475 | +void | |
| 1476 | +parse_arm_disassembler_option (option) | |
| 1477 | + char * option; | |
| 1478 | +{ | |
| 1479 | + if (option == NULL) | |
| 1480 | + return; | |
| 1481 | + | |
| 1482 | + if (strneq (option, "reg-names-", 10)) | |
| 1483 | + { | |
| 1484 | + int i; | |
| 1485 | + | |
| 1486 | + option += 10; | |
| 1487 | + | |
| 1488 | + for (i = NUM_ARM_REGNAMES; i--;) | |
| 1489 | + if (streq (option, regnames[i].name)) | |
| 1490 | + { | |
| 1491 | + regname_selected = i; | |
| 1492 | + break; | |
| 1493 | + } | |
| 1494 | + | |
| 1495 | + if (i < 0) | |
| 1496 | + fprintf (stderr, _("Unrecognised register name set: %s\n"), option); | |
| 1497 | + } | |
| 1498 | + else if (streq (option, "force-thumb")) | |
| 1499 | + force_thumb = 1; | |
| 1500 | + else if (streq (option, "no-force-thumb")) | |
| 1501 | + force_thumb = 0; | |
| 1502 | + else | |
| 1503 | + fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option); | |
| 1504 | + | |
| 1505 | + return; | |
| 1506 | +} | |
| 1507 | + | |
| 1508 | +/* Parse the string of disassembler options, spliting it at whitespaces. */ | |
| 1509 | + | |
| 1510 | +static void | |
| 1511 | +parse_disassembler_options (options) | |
| 1512 | + char * options; | |
| 1513 | +{ | |
| 1514 | + char * space; | |
| 1515 | + | |
| 1516 | + if (options == NULL) | |
| 1517 | + return; | |
| 1518 | + | |
| 1519 | + do | |
| 1520 | + { | |
| 1521 | + space = strchr (options, ' '); | |
| 1522 | + | |
| 1523 | + if (space) | |
| 1524 | + { | |
| 1525 | + * space = '\0'; | |
| 1526 | + parse_arm_disassembler_option (options); | |
| 1527 | + * space = ' '; | |
| 1528 | + options = space + 1; | |
| 1529 | + } | |
| 1530 | + else | |
| 1531 | + parse_arm_disassembler_option (options); | |
| 1532 | + } | |
| 1533 | + while (space); | |
| 1534 | +} | |
| 1535 | + | |
| 1536 | +/* NOTE: There are no checks in these routines that | |
| 1537 | + the relevant number of data bytes exist. */ | |
| 1538 | + | |
| 1539 | +int | |
| 1540 | +print_insn_arm (pc, info) | |
| 1541 | + bfd_vma pc; | |
| 1542 | + struct disassemble_info * info; | |
| 1543 | +{ | |
| 1544 | + unsigned char b[4]; | |
| 1545 | + long given; | |
| 1546 | + int status; | |
| 1547 | + int is_thumb; | |
| 1548 | + int little; | |
| 1549 | + | |
| 1550 | + if (info->disassembler_options) | |
| 1551 | + { | |
| 1552 | + parse_disassembler_options (info->disassembler_options); | |
| 1553 | + | |
| 1554 | + /* To avoid repeated parsing of these options, we remove them here. */ | |
| 1555 | + info->disassembler_options = NULL; | |
| 1556 | + } | |
| 1557 | + | |
| 1558 | + is_thumb = force_thumb; | |
| 1559 | + | |
| 1560 | +#if 0 | |
| 1561 | + if (!is_thumb && info->symbols != NULL) | |
| 1562 | + { | |
| 1563 | + if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour) | |
| 1564 | + { | |
| 1565 | + coff_symbol_type * cs; | |
| 1566 | + | |
| 1567 | + cs = coffsymbol (*info->symbols); | |
| 1568 | + is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT | |
| 1569 | + || cs->native->u.syment.n_sclass == C_THUMBSTAT | |
| 1570 | + || cs->native->u.syment.n_sclass == C_THUMBLABEL | |
| 1571 | + || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC | |
| 1572 | + || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC); | |
| 1573 | + } | |
| 1574 | + else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour) | |
| 1575 | + { | |
| 1576 | + elf_symbol_type * es; | |
| 1577 | + unsigned int type; | |
| 1578 | + | |
| 1579 | + es = *(elf_symbol_type **)(info->symbols); | |
| 1580 | + type = ELF_ST_TYPE (es->internal_elf_sym.st_info); | |
| 1581 | + | |
| 1582 | + is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT); | |
| 1583 | + } | |
| 1584 | + } | |
| 1585 | +#endif | |
| 1586 | + | |
| 1587 | + little = (info->endian == BFD_ENDIAN_LITTLE); | |
| 1588 | + info->bytes_per_chunk = 4; | |
| 1589 | + info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG; | |
| 1590 | + | |
| 1591 | + if (little) | |
| 1592 | + { | |
| 1593 | + status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info); | |
| 1594 | + if (status != 0 && is_thumb) | |
| 1595 | + { | |
| 1596 | + info->bytes_per_chunk = 2; | |
| 1597 | + | |
| 1598 | + status = info->read_memory_func (pc, (bfd_byte *) b, 2, info); | |
| 1599 | + b[3] = b[2] = 0; | |
| 1600 | + } | |
| 1601 | + | |
| 1602 | + if (status != 0) | |
| 1603 | + { | |
| 1604 | + info->memory_error_func (status, pc, info); | |
| 1605 | + return -1; | |
| 1606 | + } | |
| 1607 | + | |
| 1608 | + given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24); | |
| 1609 | + } | |
| 1610 | + else | |
| 1611 | + { | |
| 1612 | + status = info->read_memory_func | |
| 1613 | + (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info); | |
| 1614 | + if (status != 0) | |
| 1615 | + { | |
| 1616 | + info->memory_error_func (status, pc, info); | |
| 1617 | + return -1; | |
| 1618 | + } | |
| 1619 | + | |
| 1620 | + if (is_thumb) | |
| 1621 | + { | |
| 1622 | + if (pc & 0x2) | |
| 1623 | + { | |
| 1624 | + given = (b[2] << 8) | b[3]; | |
| 1625 | + | |
| 1626 | + status = info->read_memory_func | |
| 1627 | + ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info); | |
| 1628 | + if (status != 0) | |
| 1629 | + { | |
| 1630 | + info->memory_error_func (status, pc + 4, info); | |
| 1631 | + return -1; | |
| 1632 | + } | |
| 1633 | + | |
| 1634 | + given |= (b[0] << 24) | (b[1] << 16); | |
| 1635 | + } | |
| 1636 | + else | |
| 1637 | + given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16); | |
| 1638 | + } | |
| 1639 | + else | |
| 1640 | + given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]); | |
| 1641 | + } | |
| 1642 | + | |
| 1643 | + if (info->flags & INSN_HAS_RELOC) | |
| 1644 | + /* If the instruction has a reloc associated with it, then | |
| 1645 | + the offset field in the instruction will actually be the | |
| 1646 | + addend for the reloc. (We are using REL type relocs). | |
| 1647 | + In such cases, we can ignore the pc when computing | |
| 1648 | + addresses, since the addend is not currently pc-relative. */ | |
| 1649 | + pc = 0; | |
| 1650 | + if (is_thumb) | |
| 1651 | + status = print_insn_thumb (pc, info, given); | |
| 1652 | + else | |
| 1653 | + status = print_insn_arm1 (pc, info, given); | |
| 1654 | + | |
| 1655 | + return status; | |
| 1656 | +} | |
| 1657 | + | |
| 1658 | +void | |
| 1659 | +print_arm_disassembler_options (FILE * stream) | |
| 1660 | +{ | |
| 1661 | + int i; | |
| 1662 | + | |
| 1663 | + fprintf (stream, _("\n\ | |
| 1664 | +The following ARM specific disassembler options are supported for use with\n\ | |
| 1665 | +the -M switch:\n")); | |
| 1666 | + | |
| 1667 | + for (i = NUM_ARM_REGNAMES; i--;) | |
| 1668 | + fprintf (stream, " reg-names-%s %*c%s\n", | |
| 1669 | + regnames[i].name, | |
| 1670 | + (int)(14 - strlen (regnames[i].name)), ' ', | |
| 1671 | + regnames[i].description); | |
| 1672 | + | |
| 1673 | + fprintf (stream, " force-thumb Assume all insns are Thumb insns\n"); | |
| 1674 | + fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n"); | |
| 1675 | +} | ... | ... |
dis-asm.h
| ... | ... | @@ -73,16 +73,20 @@ enum bfd_architecture |
| 73 | 73 | bfd_arch_a29k, /* AMD 29000 */ |
| 74 | 74 | bfd_arch_sparc, /* SPARC */ |
| 75 | 75 | #define bfd_mach_sparc 1 |
| 76 | - /* The difference between v8plus and v9 is that v9 is a true 64 bit env. */ | |
| 76 | +/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */ | |
| 77 | 77 | #define bfd_mach_sparc_sparclet 2 |
| 78 | 78 | #define bfd_mach_sparc_sparclite 3 |
| 79 | 79 | #define bfd_mach_sparc_v8plus 4 |
| 80 | -#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns */ | |
| 81 | -#define bfd_mach_sparc_v9 6 | |
| 82 | -#define bfd_mach_sparc_v9a 7 /* with ultrasparc add'ns */ | |
| 83 | - /* Nonzero if MACH has the v9 instruction set. */ | |
| 80 | +#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */ | |
| 81 | +#define bfd_mach_sparc_sparclite_le 6 | |
| 82 | +#define bfd_mach_sparc_v9 7 | |
| 83 | +#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */ | |
| 84 | +#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */ | |
| 85 | +#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */ | |
| 86 | +/* Nonzero if MACH has the v9 instruction set. */ | |
| 84 | 87 | #define bfd_mach_sparc_v9_p(mach) \ |
| 85 | - ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9a) | |
| 88 | + ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \ | |
| 89 | + && (mach) != bfd_mach_sparc_sparclite_le) | |
| 86 | 90 | bfd_arch_mips, /* MIPS Rxxxx */ |
| 87 | 91 | #define bfd_mach_mips3000 3000 |
| 88 | 92 | #define bfd_mach_mips3900 3900 |
| ... | ... | @@ -279,6 +283,9 @@ typedef struct disassemble_info { |
| 279 | 283 | zero if unknown. */ |
| 280 | 284 | bfd_vma target2; /* Second target address for dref2 */ |
| 281 | 285 | |
| 286 | + /* Command line options specific to the target disassembler. */ | |
| 287 | + char * disassembler_options; | |
| 288 | + | |
| 282 | 289 | } disassemble_info; |
| 283 | 290 | |
| 284 | 291 | |
| ... | ... | @@ -299,8 +306,7 @@ extern int print_insn_h8300s PARAMS ((bfd_vma, disassemble_info*)); |
| 299 | 306 | extern int print_insn_h8500 PARAMS ((bfd_vma, disassemble_info*)); |
| 300 | 307 | extern int print_insn_alpha PARAMS ((bfd_vma, disassemble_info*)); |
| 301 | 308 | extern disassembler_ftype arc_get_disassembler PARAMS ((int, int)); |
| 302 | -extern int print_insn_big_arm PARAMS ((bfd_vma, disassemble_info*)); | |
| 303 | -extern int print_insn_little_arm PARAMS ((bfd_vma, disassemble_info*)); | |
| 309 | +extern int print_insn_arm PARAMS ((bfd_vma, disassemble_info*)); | |
| 304 | 310 | extern int print_insn_sparc PARAMS ((bfd_vma, disassemble_info*)); |
| 305 | 311 | extern int print_insn_big_a29k PARAMS ((bfd_vma, disassemble_info*)); |
| 306 | 312 | extern int print_insn_little_a29k PARAMS ((bfd_vma, disassemble_info*)); |
| ... | ... | @@ -381,6 +387,15 @@ extern int generic_symbol_at_address |
| 381 | 387 | (INFO).bytes_per_line = 0, \ |
| 382 | 388 | (INFO).bytes_per_chunk = 0, \ |
| 383 | 389 | (INFO).display_endian = BFD_ENDIAN_UNKNOWN, \ |
| 390 | + (INFO).disassembler_options = NULL, \ | |
| 384 | 391 | (INFO).insn_info_valid = 0 |
| 385 | 392 | |
| 393 | +#define _(x) x | |
| 394 | + | |
| 395 | +/* from libbfd */ | |
| 396 | + | |
| 397 | +bfd_vma bfd_getl32 (const bfd_byte *addr); | |
| 398 | +bfd_vma bfd_getb32 (const bfd_byte *addr); | |
| 399 | +typedef enum bfd_boolean {false, true} boolean; | |
| 400 | + | |
| 386 | 401 | #endif /* ! defined (DIS_ASM_H) */ | ... | ... |
dis-buf.c deleted
100644 → 0
| 1 | -/* Disassemble from a buffer, for GNU. | |
| 2 | - Copyright (C) 1993, 1994 Free Software Foundation, Inc. | |
| 3 | - | |
| 4 | -This program is free software; you can redistribute it and/or modify | |
| 5 | -it under the terms of the GNU General Public License as published by | |
| 6 | -the Free Software Foundation; either version 2 of the License, or | |
| 7 | -(at your option) any later version. | |
| 8 | - | |
| 9 | -This program is distributed in the hope that it will be useful, | |
| 10 | -but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 | -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 12 | -GNU General Public License for more details. | |
| 13 | - | |
| 14 | -You should have received a copy of the GNU General Public License | |
| 15 | -along with this program; if not, write to the Free Software | |
| 16 | -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
| 17 | - | |
| 18 | -#include "dis-asm.h" | |
| 19 | -#include <errno.h> | |
| 20 | - | |
| 21 | -/* Get LENGTH bytes from info's buffer, at target address memaddr. | |
| 22 | - Transfer them to myaddr. */ | |
| 23 | -int | |
| 24 | -buffer_read_memory (memaddr, myaddr, length, info) | |
| 25 | - bfd_vma memaddr; | |
| 26 | - bfd_byte *myaddr; | |
| 27 | - int length; | |
| 28 | - struct disassemble_info *info; | |
| 29 | -{ | |
| 30 | - if (memaddr < info->buffer_vma | |
| 31 | - || memaddr + length > info->buffer_vma + info->buffer_length) | |
| 32 | - /* Out of bounds. Use EIO because GDB uses it. */ | |
| 33 | - return EIO; | |
| 34 | - memcpy (myaddr, info->buffer + (memaddr - info->buffer_vma), length); | |
| 35 | - return 0; | |
| 36 | -} | |
| 37 | - | |
| 38 | -/* Print an error message. We can assume that this is in response to | |
| 39 | - an error return from buffer_read_memory. */ | |
| 40 | -void | |
| 41 | -perror_memory (status, memaddr, info) | |
| 42 | - int status; | |
| 43 | - bfd_vma memaddr; | |
| 44 | - struct disassemble_info *info; | |
| 45 | -{ | |
| 46 | - if (status != EIO) | |
| 47 | - /* Can't happen. */ | |
| 48 | - (*info->fprintf_func) (info->stream, "Unknown error %d\n", status); | |
| 49 | - else | |
| 50 | - /* Actually, address between memaddr and memaddr + len was | |
| 51 | - out of bounds. */ | |
| 52 | - (*info->fprintf_func) (info->stream, | |
| 53 | - "Address 0x%x is out of bounds.\n", memaddr); | |
| 54 | -} | |
| 55 | - | |
| 56 | -/* This could be in a separate file, to save miniscule amounts of space | |
| 57 | - in statically linked executables. */ | |
| 58 | - | |
| 59 | -/* Just print the address is hex. This is included for completeness even | |
| 60 | - though both GDB and objdump provide their own (to print symbolic | |
| 61 | - addresses). */ | |
| 62 | - | |
| 63 | -void | |
| 64 | -generic_print_address (addr, info) | |
| 65 | - bfd_vma addr; | |
| 66 | - struct disassemble_info *info; | |
| 67 | -{ | |
| 68 | - (*info->fprintf_func) (info->stream, "0x%x", addr); | |
| 69 | -} | |
| 70 | - | |
| 71 | -/* Just return the given address. */ | |
| 72 | - | |
| 73 | -int | |
| 74 | -generic_symbol_at_address (addr, info) | |
| 75 | - bfd_vma addr; | |
| 76 | - struct disassemble_info * info; | |
| 77 | -{ | |
| 78 | - return 1; | |
| 79 | -} |
disas.c
| ... | ... | @@ -2,12 +2,95 @@ |
| 2 | 2 | #include "dis-asm.h" |
| 3 | 3 | #include "disas.h" |
| 4 | 4 | #include "elf.h" |
| 5 | +#include <errno.h> | |
| 5 | 6 | |
| 6 | 7 | /* Filled in by elfload.c. Simplistic, but will do for now. */ |
| 7 | 8 | unsigned int disas_num_syms; |
| 8 | 9 | void *disas_symtab; |
| 9 | 10 | const char *disas_strtab; |
| 10 | 11 | |
| 12 | +/* Get LENGTH bytes from info's buffer, at target address memaddr. | |
| 13 | + Transfer them to myaddr. */ | |
| 14 | +int | |
| 15 | +buffer_read_memory (memaddr, myaddr, length, info) | |
| 16 | + bfd_vma memaddr; | |
| 17 | + bfd_byte *myaddr; | |
| 18 | + int length; | |
| 19 | + struct disassemble_info *info; | |
| 20 | +{ | |
| 21 | + if (memaddr < info->buffer_vma | |
| 22 | + || memaddr + length > info->buffer_vma + info->buffer_length) | |
| 23 | + /* Out of bounds. Use EIO because GDB uses it. */ | |
| 24 | + return EIO; | |
| 25 | + memcpy (myaddr, info->buffer + (memaddr - info->buffer_vma), length); | |
| 26 | + return 0; | |
| 27 | +} | |
| 28 | + | |
| 29 | +/* Print an error message. We can assume that this is in response to | |
| 30 | + an error return from buffer_read_memory. */ | |
| 31 | +void | |
| 32 | +perror_memory (status, memaddr, info) | |
| 33 | + int status; | |
| 34 | + bfd_vma memaddr; | |
| 35 | + struct disassemble_info *info; | |
| 36 | +{ | |
| 37 | + if (status != EIO) | |
| 38 | + /* Can't happen. */ | |
| 39 | + (*info->fprintf_func) (info->stream, "Unknown error %d\n", status); | |
| 40 | + else | |
| 41 | + /* Actually, address between memaddr and memaddr + len was | |
| 42 | + out of bounds. */ | |
| 43 | + (*info->fprintf_func) (info->stream, | |
| 44 | + "Address 0x%x is out of bounds.\n", memaddr); | |
| 45 | +} | |
| 46 | + | |
| 47 | +/* This could be in a separate file, to save miniscule amounts of space | |
| 48 | + in statically linked executables. */ | |
| 49 | + | |
| 50 | +/* Just print the address is hex. This is included for completeness even | |
| 51 | + though both GDB and objdump provide their own (to print symbolic | |
| 52 | + addresses). */ | |
| 53 | + | |
| 54 | +void | |
| 55 | +generic_print_address (addr, info) | |
| 56 | + bfd_vma addr; | |
| 57 | + struct disassemble_info *info; | |
| 58 | +{ | |
| 59 | + (*info->fprintf_func) (info->stream, "0x%x", addr); | |
| 60 | +} | |
| 61 | + | |
| 62 | +/* Just return the given address. */ | |
| 63 | + | |
| 64 | +int | |
| 65 | +generic_symbol_at_address (addr, info) | |
| 66 | + bfd_vma addr; | |
| 67 | + struct disassemble_info * info; | |
| 68 | +{ | |
| 69 | + return 1; | |
| 70 | +} | |
| 71 | + | |
| 72 | +bfd_vma bfd_getl32 (const bfd_byte *addr) | |
| 73 | +{ | |
| 74 | + unsigned long v; | |
| 75 | + | |
| 76 | + v = (unsigned long) addr[0]; | |
| 77 | + v |= (unsigned long) addr[1] << 8; | |
| 78 | + v |= (unsigned long) addr[2] << 16; | |
| 79 | + v |= (unsigned long) addr[3] << 24; | |
| 80 | + return (bfd_vma) v; | |
| 81 | +} | |
| 82 | + | |
| 83 | +bfd_vma bfd_getb32 (const bfd_byte *addr) | |
| 84 | +{ | |
| 85 | + unsigned long v; | |
| 86 | + | |
| 87 | + v = (unsigned long) addr[0] << 24; | |
| 88 | + v |= (unsigned long) addr[1] << 16; | |
| 89 | + v |= (unsigned long) addr[2] << 8; | |
| 90 | + v |= (unsigned long) addr[3]; | |
| 91 | + return (bfd_vma) v; | |
| 92 | +} | |
| 93 | + | |
| 11 | 94 | /* Disassemble this for me please... (debugging). */ |
| 12 | 95 | void disas(FILE *out, void *code, unsigned long size, enum disas_type type) |
| 13 | 96 | { |
| ... | ... | @@ -35,6 +118,10 @@ void disas(FILE *out, void *code, unsigned long size, enum disas_type type) |
| 35 | 118 | print_insn = print_insn_ppc; |
| 36 | 119 | #elif defined(__alpha__) |
| 37 | 120 | print_insn = print_insn_alpha; |
| 121 | +#elif defined(__sparc__) | |
| 122 | + print_insn = print_insn_sparc; | |
| 123 | +#elif defined(__arm__) | |
| 124 | + print_insn = print_insn_arm; | |
| 38 | 125 | #else |
| 39 | 126 | fprintf(out, "Asm output not supported on this arch\n"); |
| 40 | 127 | return; |
| ... | ... | @@ -51,6 +138,13 @@ void disas(FILE *out, void *code, unsigned long size, enum disas_type type) |
| 51 | 138 | |
| 52 | 139 | for (pc = code; pc < (uint8_t *)code + size; pc += count) { |
| 53 | 140 | fprintf(out, "0x%08lx: ", (long)pc); |
| 141 | +#ifdef __arm__ | |
| 142 | + /* since data are included in the code, it is better to | |
| 143 | + display code data too */ | |
| 144 | + if (type == DISAS_TARGET) { | |
| 145 | + fprintf(out, "%08x ", (int)bfd_getl32((const bfd_byte *)pc)); | |
| 146 | + } | |
| 147 | +#endif | |
| 54 | 148 | count = print_insn((unsigned long)pc, &disasm_info); |
| 55 | 149 | fprintf(out, "\n"); |
| 56 | 150 | if (count < 0) | ... | ... |
i386-dis.c
sparc-dis.c
0 → 100644
| 1 | +/* Print SPARC instructions. | |
| 2 | + Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, | |
| 3 | + 2000, 2002 Free Software Foundation, Inc. | |
| 4 | + | |
| 5 | +This program is free software; you can redistribute it and/or modify | |
| 6 | +it under the terms of the GNU General Public License as published by | |
| 7 | +the Free Software Foundation; either version 2 of the License, or | |
| 8 | +(at your option) any later version. | |
| 9 | + | |
| 10 | +This program is distributed in the hope that it will be useful, | |
| 11 | +but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 13 | +GNU General Public License for more details. | |
| 14 | + | |
| 15 | +You should have received a copy of the GNU General Public License | |
| 16 | +along with this program; if not, write to the Free Software | |
| 17 | +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
| 18 | +#include <stdlib.h> | |
| 19 | +#include "dis-asm.h" | |
| 20 | + | |
| 21 | +/* The SPARC opcode table (and other related data) is defined in | |
| 22 | + the opcodes library in sparc-opc.c. If you change anything here, make | |
| 23 | + sure you fix up that file, and vice versa. */ | |
| 24 | + | |
| 25 | + /* FIXME-someday: perhaps the ,a's and such should be embedded in the | |
| 26 | + instruction's name rather than the args. This would make gas faster, pinsn | |
| 27 | + slower, but would mess up some macros a bit. xoxorich. */ | |
| 28 | + | |
| 29 | +/* List of instruction sets variations. | |
| 30 | + These values are such that each element is either a superset of a | |
| 31 | + preceding each one or they conflict in which case SPARC_OPCODE_CONFLICT_P | |
| 32 | + returns non-zero. | |
| 33 | + The values are indices into `sparc_opcode_archs' defined in sparc-opc.c. | |
| 34 | + Don't change this without updating sparc-opc.c. */ | |
| 35 | + | |
| 36 | +enum sparc_opcode_arch_val { | |
| 37 | + SPARC_OPCODE_ARCH_V6 = 0, | |
| 38 | + SPARC_OPCODE_ARCH_V7, | |
| 39 | + SPARC_OPCODE_ARCH_V8, | |
| 40 | + SPARC_OPCODE_ARCH_SPARCLET, | |
| 41 | + SPARC_OPCODE_ARCH_SPARCLITE, | |
| 42 | + /* v9 variants must appear last */ | |
| 43 | + SPARC_OPCODE_ARCH_V9, | |
| 44 | + SPARC_OPCODE_ARCH_V9A, /* v9 with ultrasparc additions */ | |
| 45 | + SPARC_OPCODE_ARCH_V9B, /* v9 with ultrasparc and cheetah additions */ | |
| 46 | + SPARC_OPCODE_ARCH_BAD /* error return from sparc_opcode_lookup_arch */ | |
| 47 | +}; | |
| 48 | + | |
| 49 | +/* The highest architecture in the table. */ | |
| 50 | +#define SPARC_OPCODE_ARCH_MAX (SPARC_OPCODE_ARCH_BAD - 1) | |
| 51 | + | |
| 52 | +/* Given an enum sparc_opcode_arch_val, return the bitmask to use in | |
| 53 | + insn encoding/decoding. */ | |
| 54 | +#define SPARC_OPCODE_ARCH_MASK(arch) (1 << (arch)) | |
| 55 | + | |
| 56 | +/* Given a valid sparc_opcode_arch_val, return non-zero if it's v9. */ | |
| 57 | +#define SPARC_OPCODE_ARCH_V9_P(arch) ((arch) >= SPARC_OPCODE_ARCH_V9) | |
| 58 | + | |
| 59 | +/* Table of cpu variants. */ | |
| 60 | + | |
| 61 | +struct sparc_opcode_arch { | |
| 62 | + const char *name; | |
| 63 | + /* Mask of sparc_opcode_arch_val's supported. | |
| 64 | + EG: For v7 this would be | |
| 65 | + (SPARC_OPCODE_ARCH_MASK (..._V6) | SPARC_OPCODE_ARCH_MASK (..._V7)). | |
| 66 | + These are short's because sparc_opcode.architecture is. */ | |
| 67 | + short supported; | |
| 68 | +}; | |
| 69 | + | |
| 70 | +extern const struct sparc_opcode_arch sparc_opcode_archs[]; | |
| 71 | + | |
| 72 | +/* Given architecture name, look up it's sparc_opcode_arch_val value. */ | |
| 73 | +extern enum sparc_opcode_arch_val sparc_opcode_lookup_arch | |
| 74 | + PARAMS ((const char *)); | |
| 75 | + | |
| 76 | +/* Return the bitmask of supported architectures for ARCH. */ | |
| 77 | +#define SPARC_OPCODE_SUPPORTED(ARCH) (sparc_opcode_archs[ARCH].supported) | |
| 78 | + | |
| 79 | +/* Non-zero if ARCH1 conflicts with ARCH2. | |
| 80 | + IE: ARCH1 as a supported bit set that ARCH2 doesn't, and vice versa. */ | |
| 81 | +#define SPARC_OPCODE_CONFLICT_P(ARCH1, ARCH2) \ | |
| 82 | +(((SPARC_OPCODE_SUPPORTED (ARCH1) & SPARC_OPCODE_SUPPORTED (ARCH2)) \ | |
| 83 | + != SPARC_OPCODE_SUPPORTED (ARCH1)) \ | |
| 84 | + && ((SPARC_OPCODE_SUPPORTED (ARCH1) & SPARC_OPCODE_SUPPORTED (ARCH2)) \ | |
| 85 | + != SPARC_OPCODE_SUPPORTED (ARCH2))) | |
| 86 | + | |
| 87 | +/* Structure of an opcode table entry. */ | |
| 88 | + | |
| 89 | +struct sparc_opcode { | |
| 90 | + const char *name; | |
| 91 | + unsigned long match; /* Bits that must be set. */ | |
| 92 | + unsigned long lose; /* Bits that must not be set. */ | |
| 93 | + const char *args; | |
| 94 | + /* This was called "delayed" in versions before the flags. */ | |
| 95 | + char flags; | |
| 96 | + short architecture; /* Bitmask of sparc_opcode_arch_val's. */ | |
| 97 | +}; | |
| 98 | + | |
| 99 | +#define F_DELAYED 1 /* Delayed branch */ | |
| 100 | +#define F_ALIAS 2 /* Alias for a "real" instruction */ | |
| 101 | +#define F_UNBR 4 /* Unconditional branch */ | |
| 102 | +#define F_CONDBR 8 /* Conditional branch */ | |
| 103 | +#define F_JSR 16 /* Subroutine call */ | |
| 104 | +#define F_FLOAT 32 /* Floating point instruction (not a branch) */ | |
| 105 | +#define F_FBR 64 /* Floating point branch */ | |
| 106 | +/* FIXME: Add F_ANACHRONISTIC flag for v9. */ | |
| 107 | + | |
| 108 | +/* | |
| 109 | + | |
| 110 | +All sparc opcodes are 32 bits, except for the `set' instruction (really a | |
| 111 | +macro), which is 64 bits. It is handled as a special case. | |
| 112 | + | |
| 113 | +The match component is a mask saying which bits must match a particular | |
| 114 | +opcode in order for an instruction to be an instance of that opcode. | |
| 115 | + | |
| 116 | +The args component is a string containing one character for each operand of the | |
| 117 | +instruction. | |
| 118 | + | |
| 119 | +Kinds of operands: | |
| 120 | + # Number used by optimizer. It is ignored. | |
| 121 | + 1 rs1 register. | |
| 122 | + 2 rs2 register. | |
| 123 | + d rd register. | |
| 124 | + e frs1 floating point register. | |
| 125 | + v frs1 floating point register (double/even). | |
| 126 | + V frs1 floating point register (quad/multiple of 4). | |
| 127 | + f frs2 floating point register. | |
| 128 | + B frs2 floating point register (double/even). | |
| 129 | + R frs2 floating point register (quad/multiple of 4). | |
| 130 | + g frsd floating point register. | |
| 131 | + H frsd floating point register (double/even). | |
| 132 | + J frsd floating point register (quad/multiple of 4). | |
| 133 | + b crs1 coprocessor register | |
| 134 | + c crs2 coprocessor register | |
| 135 | + D crsd coprocessor register | |
| 136 | + m alternate space register (asr) in rd | |
| 137 | + M alternate space register (asr) in rs1 | |
| 138 | + h 22 high bits. | |
| 139 | + X 5 bit unsigned immediate | |
| 140 | + Y 6 bit unsigned immediate | |
| 141 | + 3 SIAM mode (3 bits). (v9b) | |
| 142 | + K MEMBAR mask (7 bits). (v9) | |
| 143 | + j 10 bit Immediate. (v9) | |
| 144 | + I 11 bit Immediate. (v9) | |
| 145 | + i 13 bit Immediate. | |
| 146 | + n 22 bit immediate. | |
| 147 | + k 2+14 bit PC relative immediate. (v9) | |
| 148 | + G 19 bit PC relative immediate. (v9) | |
| 149 | + l 22 bit PC relative immediate. | |
| 150 | + L 30 bit PC relative immediate. | |
| 151 | + a Annul. The annul bit is set. | |
| 152 | + A Alternate address space. Stored as 8 bits. | |
| 153 | + C Coprocessor state register. | |
| 154 | + F floating point state register. | |
| 155 | + p Processor state register. | |
| 156 | + N Branch predict clear ",pn" (v9) | |
| 157 | + T Branch predict set ",pt" (v9) | |
| 158 | + z %icc. (v9) | |
| 159 | + Z %xcc. (v9) | |
| 160 | + q Floating point queue. | |
| 161 | + r Single register that is both rs1 and rd. | |
| 162 | + O Single register that is both rs2 and rd. | |
| 163 | + Q Coprocessor queue. | |
| 164 | + S Special case. | |
| 165 | + t Trap base register. | |
| 166 | + w Window invalid mask register. | |
| 167 | + y Y register. | |
| 168 | + u sparclet coprocessor registers in rd position | |
| 169 | + U sparclet coprocessor registers in rs1 position | |
| 170 | + E %ccr. (v9) | |
| 171 | + s %fprs. (v9) | |
| 172 | + P %pc. (v9) | |
| 173 | + W %tick. (v9) | |
| 174 | + o %asi. (v9) | |
| 175 | + 6 %fcc0. (v9) | |
| 176 | + 7 %fcc1. (v9) | |
| 177 | + 8 %fcc2. (v9) | |
| 178 | + 9 %fcc3. (v9) | |
| 179 | + ! Privileged Register in rd (v9) | |
| 180 | + ? Privileged Register in rs1 (v9) | |
| 181 | + * Prefetch function constant. (v9) | |
| 182 | + x OPF field (v9 impdep). | |
| 183 | + 0 32/64 bit immediate for set or setx (v9) insns | |
| 184 | + _ Ancillary state register in rd (v9a) | |
| 185 | + / Ancillary state register in rs1 (v9a) | |
| 186 | + | |
| 187 | +The following chars are unused: (note: ,[] are used as punctuation) | |
| 188 | +[45] | |
| 189 | + | |
| 190 | +*/ | |
| 191 | + | |
| 192 | +#define OP2(x) (((x)&0x7) << 22) /* op2 field of format2 insns */ | |
| 193 | +#define OP3(x) (((x)&0x3f) << 19) /* op3 field of format3 insns */ | |
| 194 | +#define OP(x) ((unsigned)((x)&0x3) << 30) /* op field of all insns */ | |
| 195 | +#define OPF(x) (((x)&0x1ff) << 5) /* opf field of float insns */ | |
| 196 | +#define OPF_LOW5(x) OPF((x)&0x1f) /* v9 */ | |
| 197 | +#define F3F(x, y, z) (OP(x) | OP3(y) | OPF(z)) /* format3 float insns */ | |
| 198 | +#define F3I(x) (((x)&0x1) << 13) /* immediate field of format 3 insns */ | |
| 199 | +#define F2(x, y) (OP(x) | OP2(y)) /* format 2 insns */ | |
| 200 | +#define F3(x, y, z) (OP(x) | OP3(y) | F3I(z)) /* format3 insns */ | |
| 201 | +#define F1(x) (OP(x)) | |
| 202 | +#define DISP30(x) ((x)&0x3fffffff) | |
| 203 | +#define ASI(x) (((x)&0xff) << 5) /* asi field of format3 insns */ | |
| 204 | +#define RS2(x) ((x)&0x1f) /* rs2 field */ | |
| 205 | +#define SIMM13(x) ((x)&0x1fff) /* simm13 field */ | |
| 206 | +#define RD(x) (((x)&0x1f) << 25) /* destination register field */ | |
| 207 | +#define RS1(x) (((x)&0x1f) << 14) /* rs1 field */ | |
| 208 | +#define ASI_RS2(x) (SIMM13(x)) | |
| 209 | +#define MEMBAR(x) ((x)&0x7f) | |
| 210 | +#define SLCPOP(x) (((x)&0x7f) << 6) /* sparclet cpop */ | |
| 211 | + | |
| 212 | +#define ANNUL (1<<29) | |
| 213 | +#define BPRED (1<<19) /* v9 */ | |
| 214 | +#define IMMED F3I(1) | |
| 215 | +#define RD_G0 RD(~0) | |
| 216 | +#define RS1_G0 RS1(~0) | |
| 217 | +#define RS2_G0 RS2(~0) | |
| 218 | + | |
| 219 | +extern const struct sparc_opcode sparc_opcodes[]; | |
| 220 | +extern const int sparc_num_opcodes; | |
| 221 | + | |
| 222 | +extern int sparc_encode_asi PARAMS ((const char *)); | |
| 223 | +extern const char *sparc_decode_asi PARAMS ((int)); | |
| 224 | +extern int sparc_encode_membar PARAMS ((const char *)); | |
| 225 | +extern const char *sparc_decode_membar PARAMS ((int)); | |
| 226 | +extern int sparc_encode_prefetch PARAMS ((const char *)); | |
| 227 | +extern const char *sparc_decode_prefetch PARAMS ((int)); | |
| 228 | +extern int sparc_encode_sparclet_cpreg PARAMS ((const char *)); | |
| 229 | +extern const char *sparc_decode_sparclet_cpreg PARAMS ((int)); | |
| 230 | + | |
| 231 | +/* Some defines to make life easy. */ | |
| 232 | +#define MASK_V6 SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V6) | |
| 233 | +#define MASK_V7 SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V7) | |
| 234 | +#define MASK_V8 SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8) | |
| 235 | +#define MASK_SPARCLET SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET) | |
| 236 | +#define MASK_SPARCLITE SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE) | |
| 237 | +#define MASK_V9 SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9) | |
| 238 | +#define MASK_V9A SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A) | |
| 239 | +#define MASK_V9B SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9B) | |
| 240 | + | |
| 241 | +/* Bit masks of architectures supporting the insn. */ | |
| 242 | + | |
| 243 | +#define v6 (MASK_V6 | MASK_V7 | MASK_V8 | MASK_SPARCLET \ | |
| 244 | + | MASK_SPARCLITE | MASK_V9 | MASK_V9A | MASK_V9B) | |
| 245 | +/* v6 insns not supported on the sparclet */ | |
| 246 | +#define v6notlet (MASK_V6 | MASK_V7 | MASK_V8 \ | |
| 247 | + | MASK_SPARCLITE | MASK_V9 | MASK_V9A | MASK_V9B) | |
| 248 | +#define v7 (MASK_V7 | MASK_V8 | MASK_SPARCLET \ | |
| 249 | + | MASK_SPARCLITE | MASK_V9 | MASK_V9A | MASK_V9B) | |
| 250 | +/* Although not all insns are implemented in hardware, sparclite is defined | |
| 251 | + to be a superset of v8. Unimplemented insns trap and are then theoretically | |
| 252 | + implemented in software. | |
| 253 | + It's not clear that the same is true for sparclet, although the docs | |
| 254 | + suggest it is. Rather than complicating things, the sparclet assembler | |
| 255 | + recognizes all v8 insns. */ | |
| 256 | +#define v8 (MASK_V8 | MASK_SPARCLET | MASK_SPARCLITE \ | |
| 257 | + | MASK_V9 | MASK_V9A | MASK_V9B) | |
| 258 | +#define sparclet (MASK_SPARCLET) | |
| 259 | +#define sparclite (MASK_SPARCLITE) | |
| 260 | +#define v9 (MASK_V9 | MASK_V9A | MASK_V9B) | |
| 261 | +#define v9a (MASK_V9A | MASK_V9B) | |
| 262 | +#define v9b (MASK_V9B) | |
| 263 | +/* v6 insns not supported by v9 */ | |
| 264 | +#define v6notv9 (MASK_V6 | MASK_V7 | MASK_V8 \ | |
| 265 | + | MASK_SPARCLET | MASK_SPARCLITE) | |
| 266 | +/* v9a instructions which would appear to be aliases to v9's impdep's | |
| 267 | + otherwise */ | |
| 268 | +#define v9notv9a (MASK_V9) | |
| 269 | + | |
| 270 | +/* Table of opcode architectures. | |
| 271 | + The order is defined in opcode/sparc.h. */ | |
| 272 | + | |
| 273 | +const struct sparc_opcode_arch sparc_opcode_archs[] = { | |
| 274 | + { "v6", MASK_V6 }, | |
| 275 | + { "v7", MASK_V6 | MASK_V7 }, | |
| 276 | + { "v8", MASK_V6 | MASK_V7 | MASK_V8 }, | |
| 277 | + { "sparclet", MASK_V6 | MASK_V7 | MASK_V8 | MASK_SPARCLET }, | |
| 278 | + { "sparclite", MASK_V6 | MASK_V7 | MASK_V8 | MASK_SPARCLITE }, | |
| 279 | + /* ??? Don't some v8 priviledged insns conflict with v9? */ | |
| 280 | + { "v9", MASK_V6 | MASK_V7 | MASK_V8 | MASK_V9 }, | |
| 281 | + /* v9 with ultrasparc additions */ | |
| 282 | + { "v9a", MASK_V6 | MASK_V7 | MASK_V8 | MASK_V9 | MASK_V9A }, | |
| 283 | + /* v9 with cheetah additions */ | |
| 284 | + { "v9b", MASK_V6 | MASK_V7 | MASK_V8 | MASK_V9 | MASK_V9A | MASK_V9B }, | |
| 285 | + { NULL, 0 } | |
| 286 | +}; | |
| 287 | + | |
| 288 | +/* Given NAME, return it's architecture entry. */ | |
| 289 | + | |
| 290 | +enum sparc_opcode_arch_val | |
| 291 | +sparc_opcode_lookup_arch (name) | |
| 292 | + const char *name; | |
| 293 | +{ | |
| 294 | + const struct sparc_opcode_arch *p; | |
| 295 | + | |
| 296 | + for (p = &sparc_opcode_archs[0]; p->name; ++p) | |
| 297 | + { | |
| 298 | + if (strcmp (name, p->name) == 0) | |
| 299 | + return (enum sparc_opcode_arch_val) (p - &sparc_opcode_archs[0]); | |
| 300 | + } | |
| 301 | + | |
| 302 | + return SPARC_OPCODE_ARCH_BAD; | |
| 303 | +} | |
| 304 | + | |
| 305 | +/* Branch condition field. */ | |
| 306 | +#define COND(x) (((x)&0xf)<<25) | |
| 307 | + | |
| 308 | +/* v9: Move (MOVcc and FMOVcc) condition field. */ | |
| 309 | +#define MCOND(x,i_or_f) ((((i_or_f)&1)<<18)|(((x)>>11)&(0xf<<14))) /* v9 */ | |
| 310 | + | |
| 311 | +/* v9: Move register (MOVRcc and FMOVRcc) condition field. */ | |
| 312 | +#define RCOND(x) (((x)&0x7)<<10) /* v9 */ | |
| 313 | + | |
| 314 | +#define CONDA (COND(0x8)) | |
| 315 | +#define CONDCC (COND(0xd)) | |
| 316 | +#define CONDCS (COND(0x5)) | |
| 317 | +#define CONDE (COND(0x1)) | |
| 318 | +#define CONDG (COND(0xa)) | |
| 319 | +#define CONDGE (COND(0xb)) | |
| 320 | +#define CONDGU (COND(0xc)) | |
| 321 | +#define CONDL (COND(0x3)) | |
| 322 | +#define CONDLE (COND(0x2)) | |
| 323 | +#define CONDLEU (COND(0x4)) | |
| 324 | +#define CONDN (COND(0x0)) | |
| 325 | +#define CONDNE (COND(0x9)) | |
| 326 | +#define CONDNEG (COND(0x6)) | |
| 327 | +#define CONDPOS (COND(0xe)) | |
| 328 | +#define CONDVC (COND(0xf)) | |
| 329 | +#define CONDVS (COND(0x7)) | |
| 330 | + | |
| 331 | +#define CONDNZ CONDNE | |
| 332 | +#define CONDZ CONDE | |
| 333 | +#define CONDGEU CONDCC | |
| 334 | +#define CONDLU CONDCS | |
| 335 | + | |
| 336 | +#define FCONDA (COND(0x8)) | |
| 337 | +#define FCONDE (COND(0x9)) | |
| 338 | +#define FCONDG (COND(0x6)) | |
| 339 | +#define FCONDGE (COND(0xb)) | |
| 340 | +#define FCONDL (COND(0x4)) | |
| 341 | +#define FCONDLE (COND(0xd)) | |
| 342 | +#define FCONDLG (COND(0x2)) | |
| 343 | +#define FCONDN (COND(0x0)) | |
| 344 | +#define FCONDNE (COND(0x1)) | |
| 345 | +#define FCONDO (COND(0xf)) | |
| 346 | +#define FCONDU (COND(0x7)) | |
| 347 | +#define FCONDUE (COND(0xa)) | |
| 348 | +#define FCONDUG (COND(0x5)) | |
| 349 | +#define FCONDUGE (COND(0xc)) | |
| 350 | +#define FCONDUL (COND(0x3)) | |
| 351 | +#define FCONDULE (COND(0xe)) | |
| 352 | + | |
| 353 | +#define FCONDNZ FCONDNE | |
| 354 | +#define FCONDZ FCONDE | |
| 355 | + | |
| 356 | +#define ICC (0) /* v9 */ | |
| 357 | +#define XCC (1<<12) /* v9 */ | |
| 358 | +#define FCC(x) (((x)&0x3)<<11) /* v9 */ | |
| 359 | +#define FBFCC(x) (((x)&0x3)<<20) /* v9 */ | |
| 360 | + | |
| 361 | +/* The order of the opcodes in the table is significant: | |
| 362 | + | |
| 363 | + * The assembler requires that all instances of the same mnemonic must | |
| 364 | + be consecutive. If they aren't, the assembler will bomb at runtime. | |
| 365 | + | |
| 366 | + * The disassembler should not care about the order of the opcodes. | |
| 367 | + | |
| 368 | +*/ | |
| 369 | + | |
| 370 | +/* Entries for commutative arithmetic operations. */ | |
| 371 | +/* ??? More entries can make use of this. */ | |
| 372 | +#define COMMUTEOP(opcode, op3, arch_mask) \ | |
| 373 | +{ opcode, F3(2, op3, 0), F3(~2, ~op3, ~0)|ASI(~0), "1,2,d", 0, arch_mask }, \ | |
| 374 | +{ opcode, F3(2, op3, 1), F3(~2, ~op3, ~1), "1,i,d", 0, arch_mask }, \ | |
| 375 | +{ opcode, F3(2, op3, 1), F3(~2, ~op3, ~1), "i,1,d", 0, arch_mask } | |
| 376 | + | |
| 377 | +const struct sparc_opcode sparc_opcodes[] = { | |
| 378 | + | |
| 379 | +{ "ld", F3(3, 0x00, 0), F3(~3, ~0x00, ~0), "[1+2],d", 0, v6 }, | |
| 380 | +{ "ld", F3(3, 0x00, 0), F3(~3, ~0x00, ~0)|RS2_G0, "[1],d", 0, v6 }, /* ld [rs1+%g0],d */ | |
| 381 | +{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1), "[1+i],d", 0, v6 }, | |
| 382 | +{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1), "[i+1],d", 0, v6 }, | |
| 383 | +{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|RS1_G0, "[i],d", 0, v6 }, | |
| 384 | +{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|SIMM13(~0), "[1],d", 0, v6 }, /* ld [rs1+0],d */ | |
| 385 | +{ "ld", F3(3, 0x20, 0), F3(~3, ~0x20, ~0), "[1+2],g", 0, v6 }, | |
| 386 | +{ "ld", F3(3, 0x20, 0), F3(~3, ~0x20, ~0)|RS2_G0, "[1],g", 0, v6 }, /* ld [rs1+%g0],d */ | |
| 387 | +{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1), "[1+i],g", 0, v6 }, | |
| 388 | +{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1), "[i+1],g", 0, v6 }, | |
| 389 | +{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1)|RS1_G0, "[i],g", 0, v6 }, | |
| 390 | +{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1)|SIMM13(~0), "[1],g", 0, v6 }, /* ld [rs1+0],d */ | |
| 391 | + | |
| 392 | +{ "ld", F3(3, 0x21, 0), F3(~3, ~0x21, ~0)|RD(~0), "[1+2],F", 0, v6 }, | |
| 393 | +{ "ld", F3(3, 0x21, 0), F3(~3, ~0x21, ~0)|RS2_G0|RD(~0),"[1],F", 0, v6 }, /* ld [rs1+%g0],d */ | |
| 394 | +{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RD(~0), "[1+i],F", 0, v6 }, | |
| 395 | +{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RD(~0), "[i+1],F", 0, v6 }, | |
| 396 | +{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RS1_G0|RD(~0),"[i],F", 0, v6 }, | |
| 397 | +{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|SIMM13(~0)|RD(~0),"[1],F", 0, v6 }, /* ld [rs1+0],d */ | |
| 398 | + | |
| 399 | +{ "ld", F3(3, 0x30, 0), F3(~3, ~0x30, ~0), "[1+2],D", 0, v6notv9 }, | |
| 400 | +{ "ld", F3(3, 0x30, 0), F3(~3, ~0x30, ~0)|RS2_G0, "[1],D", 0, v6notv9 }, /* ld [rs1+%g0],d */ | |
| 401 | +{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[1+i],D", 0, v6notv9 }, | |
| 402 | +{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[i+1],D", 0, v6notv9 }, | |
| 403 | +{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|RS1_G0, "[i],D", 0, v6notv9 }, | |
| 404 | +{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|SIMM13(~0), "[1],D", 0, v6notv9 }, /* ld [rs1+0],d */ | |
| 405 | +{ "ld", F3(3, 0x31, 0), F3(~3, ~0x31, ~0), "[1+2],C", 0, v6notv9 }, | |
| 406 | +{ "ld", F3(3, 0x31, 0), F3(~3, ~0x31, ~0)|RS2_G0, "[1],C", 0, v6notv9 }, /* ld [rs1+%g0],d */ | |
| 407 | +{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1), "[1+i],C", 0, v6notv9 }, | |
| 408 | +{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1), "[i+1],C", 0, v6notv9 }, | |
| 409 | +{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|RS1_G0, "[i],C", 0, v6notv9 }, | |
| 410 | +{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|SIMM13(~0), "[1],C", 0, v6notv9 }, /* ld [rs1+0],d */ | |
| 411 | + | |
| 412 | +/* The v9 LDUW is the same as the old 'ld' opcode, it is not the same as the | |
| 413 | + 'ld' pseudo-op in v9. */ | |
| 414 | +{ "lduw", F3(3, 0x00, 0), F3(~3, ~0x00, ~0), "[1+2],d", F_ALIAS, v9 }, | |
| 415 | +{ "lduw", F3(3, 0x00, 0), F3(~3, ~0x00, ~0)|RS2_G0, "[1],d", F_ALIAS, v9 }, /* ld [rs1+%g0],d */ | |
| 416 | +{ "lduw", F3(3, 0x00, 1), F3(~3, ~0x00, ~1), "[1+i],d", F_ALIAS, v9 }, | |
| 417 | +{ "lduw", F3(3, 0x00, 1), F3(~3, ~0x00, ~1), "[i+1],d", F_ALIAS, v9 }, | |
| 418 | +{ "lduw", F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|RS1_G0, "[i],d", F_ALIAS, v9 }, | |
| 419 | +{ "lduw", F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|SIMM13(~0), "[1],d", F_ALIAS, v9 }, /* ld [rs1+0],d */ | |
| 420 | + | |
| 421 | +{ "ldd", F3(3, 0x03, 0), F3(~3, ~0x03, ~0)|ASI(~0), "[1+2],d", 0, v6 }, | |
| 422 | +{ "ldd", F3(3, 0x03, 0), F3(~3, ~0x03, ~0)|ASI_RS2(~0), "[1],d", 0, v6 }, /* ldd [rs1+%g0],d */ | |
| 423 | +{ "ldd", F3(3, 0x03, 1), F3(~3, ~0x03, ~1), "[1+i],d", 0, v6 }, | |
| 424 | +{ "ldd", F3(3, 0x03, 1), F3(~3, ~0x03, ~1), "[i+1],d", 0, v6 }, | |
| 425 | +{ "ldd", F3(3, 0x03, 1), F3(~3, ~0x03, ~1)|RS1_G0, "[i],d", 0, v6 }, | |
| 426 | +{ "ldd", F3(3, 0x03, 1), F3(~3, ~0x03, ~1)|SIMM13(~0), "[1],d", 0, v6 }, /* ldd [rs1+0],d */ | |
| 427 | +{ "ldd", F3(3, 0x23, 0), F3(~3, ~0x23, ~0)|ASI(~0), "[1+2],H", 0, v6 }, | |
| 428 | +{ "ldd", F3(3, 0x23, 0), F3(~3, ~0x23, ~0)|ASI_RS2(~0), "[1],H", 0, v6 }, /* ldd [rs1+%g0],d */ | |
| 429 | +{ "ldd", F3(3, 0x23, 1), F3(~3, ~0x23, ~1), "[1+i],H", 0, v6 }, | |
| 430 | +{ "ldd", F3(3, 0x23, 1), F3(~3, ~0x23, ~1), "[i+1],H", 0, v6 }, | |
| 431 | +{ "ldd", F3(3, 0x23, 1), F3(~3, ~0x23, ~1)|RS1_G0, "[i],H", 0, v6 }, | |
| 432 | +{ "ldd", F3(3, 0x23, 1), F3(~3, ~0x23, ~1)|SIMM13(~0), "[1],H", 0, v6 }, /* ldd [rs1+0],d */ | |
| 433 | + | |
| 434 | +{ "ldd", F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|ASI(~0), "[1+2],D", 0, v6notv9 }, | |
| 435 | +{ "ldd", F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|ASI_RS2(~0), "[1],D", 0, v6notv9 }, /* ldd [rs1+%g0],d */ | |
| 436 | +{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[1+i],D", 0, v6notv9 }, | |
| 437 | +{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[i+1],D", 0, v6notv9 }, | |
| 438 | +{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|RS1_G0, "[i],D", 0, v6notv9 }, | |
| 439 | +{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|SIMM13(~0), "[1],D", 0, v6notv9 }, /* ldd [rs1+0],d */ | |
| 440 | + | |
| 441 | +{ "ldq", F3(3, 0x22, 0), F3(~3, ~0x22, ~0)|ASI(~0), "[1+2],J", 0, v9 }, | |
| 442 | +{ "ldq", F3(3, 0x22, 0), F3(~3, ~0x22, ~0)|ASI_RS2(~0), "[1],J", 0, v9 }, /* ldd [rs1+%g0],d */ | |
| 443 | +{ "ldq", F3(3, 0x22, 1), F3(~3, ~0x22, ~1), "[1+i],J", 0, v9 }, | |
| 444 | +{ "ldq", F3(3, 0x22, 1), F3(~3, ~0x22, ~1), "[i+1],J", 0, v9 }, | |
| 445 | +{ "ldq", F3(3, 0x22, 1), F3(~3, ~0x22, ~1)|RS1_G0, "[i],J", 0, v9 }, | |
| 446 | +{ "ldq", F3(3, 0x22, 1), F3(~3, ~0x22, ~1)|SIMM13(~0), "[1],J", 0, v9 }, /* ldd [rs1+0],d */ | |
| 447 | + | |
| 448 | +{ "ldsb", F3(3, 0x09, 0), F3(~3, ~0x09, ~0)|ASI(~0), "[1+2],d", 0, v6 }, | |
| 449 | +{ "ldsb", F3(3, 0x09, 0), F3(~3, ~0x09, ~0)|ASI_RS2(~0), "[1],d", 0, v6 }, /* ldsb [rs1+%g0],d */ | |
| 450 | +{ "ldsb", F3(3, 0x09, 1), F3(~3, ~0x09, ~1), "[1+i],d", 0, v6 }, | |
| 451 | +{ "ldsb", F3(3, 0x09, 1), F3(~3, ~0x09, ~1), "[i+1],d", 0, v6 }, | |
| 452 | +{ "ldsb", F3(3, 0x09, 1), F3(~3, ~0x09, ~1)|RS1_G0, "[i],d", 0, v6 }, | |
| 453 | +{ "ldsb", F3(3, 0x09, 1), F3(~3, ~0x09, ~1)|SIMM13(~0), "[1],d", 0, v6 }, /* ldsb [rs1+0],d */ | |
| 454 | + | |
| 455 | +{ "ldsh", F3(3, 0x0a, 0), F3(~3, ~0x0a, ~0)|ASI_RS2(~0), "[1],d", 0, v6 }, /* ldsh [rs1+%g0],d */ | |
| 456 | +{ "ldsh", F3(3, 0x0a, 0), F3(~3, ~0x0a, ~0)|ASI(~0), "[1+2],d", 0, v6 }, | |
| 457 | +{ "ldsh", F3(3, 0x0a, 1), F3(~3, ~0x0a, ~1), "[1+i],d", 0, v6 }, | |
| 458 | +{ "ldsh", F3(3, 0x0a, 1), F3(~3, ~0x0a, ~1), "[i+1],d", 0, v6 }, | |
| 459 | +{ "ldsh", F3(3, 0x0a, 1), F3(~3, ~0x0a, ~1)|RS1_G0, "[i],d", 0, v6 }, | |
| 460 | +{ "ldsh", F3(3, 0x0a, 1), F3(~3, ~0x0a, ~1)|SIMM13(~0), "[1],d", 0, v6 }, /* ldsh [rs1+0],d */ | |
| 461 | + | |
| 462 | +{ "ldstub", F3(3, 0x0d, 0), F3(~3, ~0x0d, ~0)|ASI(~0), "[1+2],d", 0, v6 }, | |
| 463 | +{ "ldstub", F3(3, 0x0d, 0), F3(~3, ~0x0d, ~0)|ASI_RS2(~0), "[1],d", 0, v6 }, /* ldstub [rs1+%g0],d */ | |
| 464 | +{ "ldstub", F3(3, 0x0d, 1), F3(~3, ~0x0d, ~1), "[1+i],d", 0, v6 }, | |
| 465 | +{ "ldstub", F3(3, 0x0d, 1), F3(~3, ~0x0d, ~1), "[i+1],d", 0, v6 }, | |
| 466 | +{ "ldstub", F3(3, 0x0d, 1), F3(~3, ~0x0d, ~1)|RS1_G0, "[i],d", 0, v6 }, | |
| 467 | +{ "ldstub", F3(3, 0x0d, 1), F3(~3, ~0x0d, ~1)|SIMM13(~0), "[1],d", 0, v6 }, /* ldstub [rs1+0],d */ | |
| 468 | + | |
| 469 | +{ "ldsw", F3(3, 0x08, 0), F3(~3, ~0x08, ~0)|ASI(~0), "[1+2],d", 0, v9 }, | |
| 470 | +{ "ldsw", F3(3, 0x08, 0), F3(~3, ~0x08, ~0)|ASI_RS2(~0), "[1],d", 0, v9 }, /* ldsw [rs1+%g0],d */ | |
| 471 | +{ "ldsw", F3(3, 0x08, 1), F3(~3, ~0x08, ~1), "[1+i],d", 0, v9 }, | |
| 472 | +{ "ldsw", F3(3, 0x08, 1), F3(~3, ~0x08, ~1), "[i+1],d", 0, v9 }, | |
| 473 | +{ "ldsw", F3(3, 0x08, 1), F3(~3, ~0x08, ~1)|RS1_G0, "[i],d", 0, v9 }, | |
| 474 | +{ "ldsw", F3(3, 0x08, 1), F3(~3, ~0x08, ~1)|SIMM13(~0), "[1],d", 0, v9 }, /* ldsw [rs1+0],d */ | |
| 475 | + | |
| 476 | +{ "ldub", F3(3, 0x01, 0), F3(~3, ~0x01, ~0)|ASI(~0), "[1+2],d", 0, v6 }, | |
| 477 | +{ "ldub", F3(3, 0x01, 0), F3(~3, ~0x01, ~0)|ASI_RS2(~0), "[1],d", 0, v6 }, /* ldub [rs1+%g0],d */ | |
| 478 | +{ "ldub", F3(3, 0x01, 1), F3(~3, ~0x01, ~1), "[1+i],d", 0, v6 }, | |
| 479 | +{ "ldub", F3(3, 0x01, 1), F3(~3, ~0x01, ~1), "[i+1],d", 0, v6 }, | |
| 480 | +{ "ldub", F3(3, 0x01, 1), F3(~3, ~0x01, ~1)|RS1_G0, "[i],d", 0, v6 }, | |
| 481 | +{ "ldub", F3(3, 0x01, 1), F3(~3, ~0x01, ~1)|SIMM13(~0), "[1],d", 0, v6 }, /* ldub [rs1+0],d */ | |
| 482 | + | |
| 483 | +{ "lduh", F3(3, 0x02, 0), F3(~3, ~0x02, ~0)|ASI(~0), "[1+2],d", 0, v6 }, | |
| 484 | +{ "lduh", F3(3, 0x02, 0), F3(~3, ~0x02, ~0)|ASI_RS2(~0), "[1],d", 0, v6 }, /* lduh [rs1+%g0],d */ | |
| 485 | +{ "lduh", F3(3, 0x02, 1), F3(~3, ~0x02, ~1), "[1+i],d", 0, v6 }, | |
| 486 | +{ "lduh", F3(3, 0x02, 1), F3(~3, ~0x02, ~1), "[i+1],d", 0, v6 }, | |
| 487 | +{ "lduh", F3(3, 0x02, 1), F3(~3, ~0x02, ~1)|RS1_G0, "[i],d", 0, v6 }, | |
| 488 | +{ "lduh", F3(3, 0x02, 1), F3(~3, ~0x02, ~1)|SIMM13(~0), "[1],d", 0, v6 }, /* lduh [rs1+0],d */ | |
| 489 | + | |
| 490 | +{ "ldx", F3(3, 0x0b, 0), F3(~3, ~0x0b, ~0)|ASI(~0), "[1+2],d", 0, v9 }, | |
| 491 | +{ "ldx", F3(3, 0x0b, 0), F3(~3, ~0x0b, ~0)|ASI_RS2(~0), "[1],d", 0, v9 }, /* ldx [rs1+%g0],d */ | |
| 492 | +{ "ldx", F3(3, 0x0b, 1), F3(~3, ~0x0b, ~1), "[1+i],d", 0, v9 }, | |
| 493 | +{ "ldx", F3(3, 0x0b, 1), F3(~3, ~0x0b, ~1), "[i+1],d", 0, v9 }, | |
| 494 | +{ "ldx", F3(3, 0x0b, 1), F3(~3, ~0x0b, ~1)|RS1_G0, "[i],d", 0, v9 }, | |
| 495 | +{ "ldx", F3(3, 0x0b, 1), F3(~3, ~0x0b, ~1)|SIMM13(~0), "[1],d", 0, v9 }, /* ldx [rs1+0],d */ | |
| 496 | + | |
| 497 | +{ "ldx", F3(3, 0x21, 0)|RD(1), F3(~3, ~0x21, ~0)|RD(~1), "[1+2],F", 0, v9 }, | |
| 498 | +{ "ldx", F3(3, 0x21, 0)|RD(1), F3(~3, ~0x21, ~0)|RS2_G0|RD(~1), "[1],F", 0, v9 }, /* ld [rs1+%g0],d */ | |
| 499 | +{ "ldx", F3(3, 0x21, 1)|RD(1), F3(~3, ~0x21, ~1)|RD(~1), "[1+i],F", 0, v9 }, | |
| 500 | +{ "ldx", F3(3, 0x21, 1)|RD(1), F3(~3, ~0x21, ~1)|RD(~1), "[i+1],F", 0, v9 }, | |
| 501 | +{ "ldx", F3(3, 0x21, 1)|RD(1), F3(~3, ~0x21, ~1)|RS1_G0|RD(~1), "[i],F", 0, v9 }, | |
| 502 | +{ "ldx", F3(3, 0x21, 1)|RD(1), F3(~3, ~0x21, ~1)|SIMM13(~0)|RD(~1),"[1],F", 0, v9 }, /* ld [rs1+0],d */ | |
| 503 | + | |
| 504 | +{ "lda", F3(3, 0x10, 0), F3(~3, ~0x10, ~0), "[1+2]A,d", 0, v6 }, | |
| 505 | +{ "lda", F3(3, 0x10, 0), F3(~3, ~0x10, ~0)|RS2_G0, "[1]A,d", 0, v6 }, /* lda [rs1+%g0],d */ | |
| 506 | +{ "lda", F3(3, 0x10, 1), F3(~3, ~0x10, ~1), "[1+i]o,d", 0, v9 }, | |
| 507 | +{ "lda", F3(3, 0x10, 1), F3(~3, ~0x10, ~1), "[i+1]o,d", 0, v9 }, | |
| 508 | +{ "lda", F3(3, 0x10, 1), F3(~3, ~0x10, ~1)|RS1_G0, "[i]o,d", 0, v9 }, | |
| 509 | +{ "lda", F3(3, 0x10, 1), F3(~3, ~0x10, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */ | |
| 510 | +{ "lda", F3(3, 0x30, 0), F3(~3, ~0x30, ~0), "[1+2]A,g", 0, v9 }, | |
| 511 | +{ "lda", F3(3, 0x30, 0), F3(~3, ~0x30, ~0)|RS2_G0, "[1]A,g", 0, v9 }, /* lda [rs1+%g0],d */ | |
| 512 | +{ "lda", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[1+i]o,g", 0, v9 }, | |
| 513 | +{ "lda", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[i+1]o,g", 0, v9 }, | |
| 514 | +{ "lda", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|RS1_G0, "[i]o,g", 0, v9 }, | |
| 515 | +{ "lda", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|SIMM13(~0), "[1]o,g", 0, v9 }, /* ld [rs1+0],d */ | |
| 516 | + | |
| 517 | +{ "ldda", F3(3, 0x13, 0), F3(~3, ~0x13, ~0), "[1+2]A,d", 0, v6 }, | |
| 518 | +{ "ldda", F3(3, 0x13, 0), F3(~3, ~0x13, ~0)|RS2_G0, "[1]A,d", 0, v6 }, /* ldda [rs1+%g0],d */ | |
| 519 | +{ "ldda", F3(3, 0x13, 1), F3(~3, ~0x13, ~1), "[1+i]o,d", 0, v9 }, | |
| 520 | +{ "ldda", F3(3, 0x13, 1), F3(~3, ~0x13, ~1), "[i+1]o,d", 0, v9 }, | |
| 521 | +{ "ldda", F3(3, 0x13, 1), F3(~3, ~0x13, ~1)|RS1_G0, "[i]o,d", 0, v9 }, | |
| 522 | +{ "ldda", F3(3, 0x13, 1), F3(~3, ~0x13, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */ | |
| 523 | + | |
| 524 | +{ "ldda", F3(3, 0x33, 0), F3(~3, ~0x33, ~0), "[1+2]A,H", 0, v9 }, | |
| 525 | +{ "ldda", F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|RS2_G0, "[1]A,H", 0, v9 }, /* ldda [rs1+%g0],d */ | |
| 526 | +{ "ldda", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[1+i]o,H", 0, v9 }, | |
| 527 | +{ "ldda", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[i+1]o,H", 0, v9 }, | |
| 528 | +{ "ldda", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|RS1_G0, "[i]o,H", 0, v9 }, | |
| 529 | +{ "ldda", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|SIMM13(~0), "[1]o,H", 0, v9 }, /* ld [rs1+0],d */ | |
| 530 | + | |
| 531 | +{ "ldqa", F3(3, 0x32, 0), F3(~3, ~0x32, ~0), "[1+2]A,J", 0, v9 }, | |
| 532 | +{ "ldqa", F3(3, 0x32, 0), F3(~3, ~0x32, ~0)|RS2_G0, "[1]A,J", 0, v9 }, /* ldd [rs1+%g0],d */ | |
| 533 | +{ "ldqa", F3(3, 0x32, 1), F3(~3, ~0x32, ~1), "[1+i]o,J", 0, v9 }, | |
| 534 | +{ "ldqa", F3(3, 0x32, 1), F3(~3, ~0x32, ~1), "[i+1]o,J", 0, v9 }, | |
| 535 | +{ "ldqa", F3(3, 0x32, 1), F3(~3, ~0x32, ~1)|RS1_G0, "[i]o,J", 0, v9 }, | |
| 536 | +{ "ldqa", F3(3, 0x32, 1), F3(~3, ~0x32, ~1)|SIMM13(~0), "[1]o,J", 0, v9 }, /* ldd [rs1+0],d */ | |
| 537 | + | |
| 538 | +{ "ldsba", F3(3, 0x19, 0), F3(~3, ~0x19, ~0), "[1+2]A,d", 0, v6 }, | |
| 539 | +{ "ldsba", F3(3, 0x19, 0), F3(~3, ~0x19, ~0)|RS2_G0, "[1]A,d", 0, v6 }, /* ldsba [rs1+%g0],d */ | |
| 540 | +{ "ldsba", F3(3, 0x19, 1), F3(~3, ~0x19, ~1), "[1+i]o,d", 0, v9 }, | |
| 541 | +{ "ldsba", F3(3, 0x19, 1), F3(~3, ~0x19, ~1), "[i+1]o,d", 0, v9 }, | |
| 542 | +{ "ldsba", F3(3, 0x19, 1), F3(~3, ~0x19, ~1)|RS1_G0, "[i]o,d", 0, v9 }, | |
| 543 | +{ "ldsba", F3(3, 0x19, 1), F3(~3, ~0x19, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */ | |
| 544 | + | |
| 545 | +{ "ldsha", F3(3, 0x1a, 0), F3(~3, ~0x1a, ~0), "[1+2]A,d", 0, v6 }, | |
| 546 | +{ "ldsha", F3(3, 0x1a, 0), F3(~3, ~0x1a, ~0)|RS2_G0, "[1]A,d", 0, v6 }, /* ldsha [rs1+%g0],d */ | |
| 547 | +{ "ldsha", F3(3, 0x1a, 1), F3(~3, ~0x1a, ~1), "[1+i]o,d", 0, v9 }, | |
| 548 | +{ "ldsha", F3(3, 0x1a, 1), F3(~3, ~0x1a, ~1), "[i+1]o,d", 0, v9 }, | |
| 549 | +{ "ldsha", F3(3, 0x1a, 1), F3(~3, ~0x1a, ~1)|RS1_G0, "[i]o,d", 0, v9 }, | |
| 550 | +{ "ldsha", F3(3, 0x1a, 1), F3(~3, ~0x1a, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */ | |
| 551 | + | |
| 552 | +{ "ldstuba", F3(3, 0x1d, 0), F3(~3, ~0x1d, ~0), "[1+2]A,d", 0, v6 }, | |
| 553 | +{ "ldstuba", F3(3, 0x1d, 0), F3(~3, ~0x1d, ~0)|RS2_G0, "[1]A,d", 0, v6 }, /* ldstuba [rs1+%g0],d */ | |
| 554 | +{ "ldstuba", F3(3, 0x1d, 1), F3(~3, ~0x1d, ~1), "[1+i]o,d", 0, v9 }, | |
| 555 | +{ "ldstuba", F3(3, 0x1d, 1), F3(~3, ~0x1d, ~1), "[i+1]o,d", 0, v9 }, | |
| 556 | +{ "ldstuba", F3(3, 0x1d, 1), F3(~3, ~0x1d, ~1)|RS1_G0, "[i]o,d", 0, v9 }, | |
| 557 | +{ "ldstuba", F3(3, 0x1d, 1), F3(~3, ~0x1d, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */ | |
| 558 | + | |
| 559 | +{ "ldswa", F3(3, 0x18, 0), F3(~3, ~0x18, ~0), "[1+2]A,d", 0, v9 }, | |
| 560 | +{ "ldswa", F3(3, 0x18, 0), F3(~3, ~0x18, ~0)|RS2_G0, "[1]A,d", 0, v9 }, /* lda [rs1+%g0],d */ | |
| 561 | +{ "ldswa", F3(3, 0x18, 1), F3(~3, ~0x18, ~1), "[1+i]o,d", 0, v9 }, | |
| 562 | +{ "ldswa", F3(3, 0x18, 1), F3(~3, ~0x18, ~1), "[i+1]o,d", 0, v9 }, | |
| 563 | +{ "ldswa", F3(3, 0x18, 1), F3(~3, ~0x18, ~1)|RS1_G0, "[i]o,d", 0, v9 }, | |
| 564 | +{ "ldswa", F3(3, 0x18, 1), F3(~3, ~0x18, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */ | |
| 565 | + | |
| 566 | +{ "lduba", F3(3, 0x11, 0), F3(~3, ~0x11, ~0), "[1+2]A,d", 0, v6 }, | |
| 567 | +{ "lduba", F3(3, 0x11, 0), F3(~3, ~0x11, ~0)|RS2_G0, "[1]A,d", 0, v6 }, /* lduba [rs1+%g0],d */ | |
| 568 | +{ "lduba", F3(3, 0x11, 1), F3(~3, ~0x11, ~1), "[1+i]o,d", 0, v9 }, | |
| 569 | +{ "lduba", F3(3, 0x11, 1), F3(~3, ~0x11, ~1), "[i+1]o,d", 0, v9 }, | |
| 570 | +{ "lduba", F3(3, 0x11, 1), F3(~3, ~0x11, ~1)|RS1_G0, "[i]o,d", 0, v9 }, | |
| 571 | +{ "lduba", F3(3, 0x11, 1), F3(~3, ~0x11, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */ | |
| 572 | + | |
| 573 | +{ "lduha", F3(3, 0x12, 0), F3(~3, ~0x12, ~0), "[1+2]A,d", 0, v6 }, | |
| 574 | +{ "lduha", F3(3, 0x12, 0), F3(~3, ~0x12, ~0)|RS2_G0, "[1]A,d", 0, v6 }, /* lduha [rs1+%g0],d */ | |
| 575 | +{ "lduha", F3(3, 0x12, 1), F3(~3, ~0x12, ~1), "[1+i]o,d", 0, v9 }, | |
| 576 | +{ "lduha", F3(3, 0x12, 1), F3(~3, ~0x12, ~1), "[i+1]o,d", 0, v9 }, | |
| 577 | +{ "lduha", F3(3, 0x12, 1), F3(~3, ~0x12, ~1)|RS1_G0, "[i]o,d", 0, v9 }, | |
| 578 | +{ "lduha", F3(3, 0x12, 1), F3(~3, ~0x12, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */ | |
| 579 | + | |
| 580 | +{ "lduwa", F3(3, 0x10, 0), F3(~3, ~0x10, ~0), "[1+2]A,d", F_ALIAS, v9 }, /* lduwa === lda */ | |
| 581 | +{ "lduwa", F3(3, 0x10, 0), F3(~3, ~0x10, ~0)|RS2_G0, "[1]A,d", F_ALIAS, v9 }, /* lda [rs1+%g0],d */ | |
| 582 | +{ "lduwa", F3(3, 0x10, 1), F3(~3, ~0x10, ~1), "[1+i]o,d", F_ALIAS, v9 }, | |
| 583 | +{ "lduwa", F3(3, 0x10, 1), F3(~3, ~0x10, ~1), "[i+1]o,d", F_ALIAS, v9 }, | |
| 584 | +{ "lduwa", F3(3, 0x10, 1), F3(~3, ~0x10, ~1)|RS1_G0, "[i]o,d", F_ALIAS, v9 }, | |
| 585 | +{ "lduwa", F3(3, 0x10, 1), F3(~3, ~0x10, ~1)|SIMM13(~0), "[1]o,d", F_ALIAS, v9 }, /* ld [rs1+0],d */ | |
| 586 | + | |
| 587 | +{ "ldxa", F3(3, 0x1b, 0), F3(~3, ~0x1b, ~0), "[1+2]A,d", 0, v9 }, | |
| 588 | +{ "ldxa", F3(3, 0x1b, 0), F3(~3, ~0x1b, ~0)|RS2_G0, "[1]A,d", 0, v9 }, /* lda [rs1+%g0],d */ | |
| 589 | +{ "ldxa", F3(3, 0x1b, 1), F3(~3, ~0x1b, ~1), "[1+i]o,d", 0, v9 }, | |
| 590 | +{ "ldxa", F3(3, 0x1b, 1), F3(~3, ~0x1b, ~1), "[i+1]o,d", 0, v9 }, | |
| 591 | +{ "ldxa", F3(3, 0x1b, 1), F3(~3, ~0x1b, ~1)|RS1_G0, "[i]o,d", 0, v9 }, | |
| 592 | +{ "ldxa", F3(3, 0x1b, 1), F3(~3, ~0x1b, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */ | |
| 593 | + | |
| 594 | +{ "st", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI(~0), "d,[1+2]", 0, v6 }, | |
| 595 | +{ "st", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI_RS2(~0), "d,[1]", 0, v6 }, /* st d,[rs1+%g0] */ | |
| 596 | +{ "st", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[1+i]", 0, v6 }, | |
| 597 | +{ "st", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[i+1]", 0, v6 }, | |
| 598 | +{ "st", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RS1_G0, "d,[i]", 0, v6 }, | |
| 599 | +{ "st", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|SIMM13(~0), "d,[1]", 0, v6 }, /* st d,[rs1+0] */ | |
| 600 | +{ "st", F3(3, 0x24, 0), F3(~3, ~0x24, ~0)|ASI(~0), "g,[1+2]", 0, v6 }, | |
| 601 | +{ "st", F3(3, 0x24, 0), F3(~3, ~0x24, ~0)|ASI_RS2(~0), "g,[1]", 0, v6 }, /* st d[rs1+%g0] */ | |
| 602 | +{ "st", F3(3, 0x24, 1), F3(~3, ~0x24, ~1), "g,[1+i]", 0, v6 }, | |
| 603 | +{ "st", F3(3, 0x24, 1), F3(~3, ~0x24, ~1), "g,[i+1]", 0, v6 }, | |
| 604 | +{ "st", F3(3, 0x24, 1), F3(~3, ~0x24, ~1)|RS1_G0, "g,[i]", 0, v6 }, | |
| 605 | +{ "st", F3(3, 0x24, 1), F3(~3, ~0x24, ~1)|SIMM13(~0), "g,[1]", 0, v6 }, /* st d,[rs1+0] */ | |
| 606 | + | |
| 607 | +{ "st", F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|ASI(~0), "D,[1+2]", 0, v6notv9 }, | |
| 608 | +{ "st", F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|ASI_RS2(~0), "D,[1]", 0, v6notv9 }, /* st d,[rs1+%g0] */ | |
| 609 | +{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1), "D,[1+i]", 0, v6notv9 }, | |
| 610 | +{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1), "D,[i+1]", 0, v6notv9 }, | |
| 611 | +{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|RS1_G0, "D,[i]", 0, v6notv9 }, | |
| 612 | +{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|SIMM13(~0), "D,[1]", 0, v6notv9 }, /* st d,[rs1+0] */ | |
| 613 | +{ "st", F3(3, 0x35, 0), F3(~3, ~0x35, ~0)|ASI(~0), "C,[1+2]", 0, v6notv9 }, | |
| 614 | +{ "st", F3(3, 0x35, 0), F3(~3, ~0x35, ~0)|ASI_RS2(~0), "C,[1]", 0, v6notv9 }, /* st d,[rs1+%g0] */ | |
| 615 | +{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1), "C,[1+i]", 0, v6notv9 }, | |
| 616 | +{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1), "C,[i+1]", 0, v6notv9 }, | |
| 617 | +{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1)|RS1_G0, "C,[i]", 0, v6notv9 }, | |
| 618 | +{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1)|SIMM13(~0), "C,[1]", 0, v6notv9 }, /* st d,[rs1+0] */ | |
| 619 | + | |
| 620 | +{ "st", F3(3, 0x25, 0), F3(~3, ~0x25, ~0)|RD_G0|ASI(~0), "F,[1+2]", 0, v6 }, | |
| 621 | +{ "st", F3(3, 0x25, 0), F3(~3, ~0x25, ~0)|RD_G0|ASI_RS2(~0), "F,[1]", 0, v6 }, /* st d,[rs1+%g0] */ | |
| 622 | +{ "st", F3(3, 0x25, 1), F3(~3, ~0x25, ~1)|RD_G0, "F,[1+i]", 0, v6 }, | |
| 623 | +{ "st", F3(3, 0x25, 1), F3(~3, ~0x25, ~1)|RD_G0, "F,[i+1]", 0, v6 }, | |
| 624 | +{ "st", F3(3, 0x25, 1), F3(~3, ~0x25, ~1)|RD_G0|RS1_G0, "F,[i]", 0, v6 }, | |
| 625 | +{ "st", F3(3, 0x25, 1), F3(~3, ~0x25, ~1)|RD_G0|SIMM13(~0), "F,[1]", 0, v6 }, /* st d,[rs1+0] */ | |
| 626 | + | |
| 627 | +{ "stw", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v9 }, | |
| 628 | +{ "stw", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v9 }, /* st d,[rs1+%g0] */ | |
| 629 | +{ "stw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[1+i]", F_ALIAS, v9 }, | |
| 630 | +{ "stw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[i+1]", F_ALIAS, v9 }, | |
| 631 | +{ "stw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RS1_G0, "d,[i]", F_ALIAS, v9 }, | |
| 632 | +{ "stw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v9 }, /* st d,[rs1+0] */ | |
| 633 | +{ "stsw", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v9 }, | |
| 634 | +{ "stsw", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v9 }, /* st d,[rs1+%g0] */ | |
| 635 | +{ "stsw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[1+i]", F_ALIAS, v9 }, | |
| 636 | +{ "stsw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[i+1]", F_ALIAS, v9 }, | |
| 637 | +{ "stsw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RS1_G0, "d,[i]", F_ALIAS, v9 }, | |
| 638 | +{ "stsw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v9 }, /* st d,[rs1+0] */ | |
| 639 | +{ "stuw", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v9 }, | |
| 640 | +{ "stuw", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v9 }, /* st d,[rs1+%g0] */ | |
| 641 | +{ "stuw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[1+i]", F_ALIAS, v9 }, | |
| 642 | +{ "stuw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[i+1]", F_ALIAS, v9 }, | |
| 643 | +{ "stuw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RS1_G0, "d,[i]", F_ALIAS, v9 }, | |
| 644 | +{ "stuw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v9 }, /* st d,[rs1+0] */ | |
| 645 | + | |
| 646 | +{ "spill", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v6 }, | |
| 647 | +{ "spill", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v6 }, /* st d,[rs1+%g0] */ | |
| 648 | +{ "spill", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[1+i]", F_ALIAS, v6 }, | |
| 649 | +{ "spill", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[i+1]", F_ALIAS, v6 }, | |
| 650 | +{ "spill", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RS1_G0, "d,[i]", F_ALIAS, v6 }, | |
| 651 | +{ "spill", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v6 }, /* st d,[rs1+0] */ | |
| 652 | + | |
| 653 | +{ "sta", F3(3, 0x14, 0), F3(~3, ~0x14, ~0), "d,[1+2]A", 0, v6 }, | |
| 654 | +{ "sta", F3(3, 0x14, 0), F3(~3, ~0x14, ~0)|RS2(~0), "d,[1]A", 0, v6 }, /* sta d,[rs1+%g0] */ | |
| 655 | +{ "sta", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[1+i]o", 0, v9 }, | |
| 656 | +{ "sta", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[i+1]o", 0, v9 }, | |
| 657 | +{ "sta", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|RS1_G0, "d,[i]o", 0, v9 }, | |
| 658 | +{ "sta", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|SIMM13(~0), "d,[1]o", 0, v9 }, /* st d,[rs1+0] */ | |
| 659 | + | |
| 660 | +{ "sta", F3(3, 0x34, 0), F3(~3, ~0x34, ~0), "g,[1+2]A", 0, v9 }, | |
| 661 | +{ "sta", F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|RS2(~0), "g,[1]A", 0, v9 }, /* sta d,[rs1+%g0] */ | |
| 662 | +{ "sta", F3(3, 0x34, 1), F3(~3, ~0x34, ~1), "g,[1+i]o", 0, v9 }, | |
| 663 | +{ "sta", F3(3, 0x34, 1), F3(~3, ~0x34, ~1), "g,[i+1]o", 0, v9 }, | |
| 664 | +{ "sta", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|RS1_G0, "g,[i]o", 0, v9 }, | |
| 665 | +{ "sta", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|SIMM13(~0), "g,[1]o", 0, v9 }, /* st d,[rs1+0] */ | |
| 666 | + | |
| 667 | +{ "stwa", F3(3, 0x14, 0), F3(~3, ~0x14, ~0), "d,[1+2]A", F_ALIAS, v9 }, | |
| 668 | +{ "stwa", F3(3, 0x14, 0), F3(~3, ~0x14, ~0)|RS2(~0), "d,[1]A", F_ALIAS, v9 }, /* sta d,[rs1+%g0] */ | |
| 669 | +{ "stwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[1+i]o", F_ALIAS, v9 }, | |
| 670 | +{ "stwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[i+1]o", F_ALIAS, v9 }, | |
| 671 | +{ "stwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|RS1_G0, "d,[i]o", F_ALIAS, v9 }, | |
| 672 | +{ "stwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|SIMM13(~0), "d,[1]o", F_ALIAS, v9 }, /* st d,[rs1+0] */ | |
| 673 | +{ "stswa", F3(3, 0x14, 0), F3(~3, ~0x14, ~0), "d,[1+2]A", F_ALIAS, v9 }, | |
| 674 | +{ "stswa", F3(3, 0x14, 0), F3(~3, ~0x14, ~0)|RS2(~0), "d,[1]A", F_ALIAS, v9 }, /* sta d,[rs1+%g0] */ | |
| 675 | +{ "stswa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[1+i]o", F_ALIAS, v9 }, | |
| 676 | +{ "stswa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[i+1]o", F_ALIAS, v9 }, | |
| 677 | +{ "stswa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|RS1_G0, "d,[i]o", F_ALIAS, v9 }, | |
| 678 | +{ "stswa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|SIMM13(~0), "d,[1]o", F_ALIAS, v9 }, /* st d,[rs1+0] */ | |
| 679 | +{ "stuwa", F3(3, 0x14, 0), F3(~3, ~0x14, ~0), "d,[1+2]A", F_ALIAS, v9 }, | |
| 680 | +{ "stuwa", F3(3, 0x14, 0), F3(~3, ~0x14, ~0)|RS2(~0), "d,[1]A", F_ALIAS, v9 }, /* sta d,[rs1+%g0] */ | |
| 681 | +{ "stuwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[1+i]o", F_ALIAS, v9 }, | |
| 682 | +{ "stuwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[i+1]o", F_ALIAS, v9 }, | |
| 683 | +{ "stuwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|RS1_G0, "d,[i]o", F_ALIAS, v9 }, | |
| 684 | +{ "stuwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|SIMM13(~0), "d,[1]o", F_ALIAS, v9 }, /* st d,[rs1+0] */ | |
| 685 | + | |
| 686 | +{ "stb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI(~0), "d,[1+2]", 0, v6 }, | |
| 687 | +{ "stb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI_RS2(~0), "d,[1]", 0, v6 }, /* stb d,[rs1+%g0] */ | |
| 688 | +{ "stb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1), "d,[1+i]", 0, v6 }, | |
| 689 | +{ "stb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1), "d,[i+1]", 0, v6 }, | |
| 690 | +{ "stb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RS1_G0, "d,[i]", 0, v6 }, | |
| 691 | +{ "stb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|SIMM13(~0), "d,[1]", 0, v6 }, /* stb d,[rs1+0] */ | |
| 692 | + | |
| 693 | +{ "stsb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v6 }, | |
| 694 | +{ "stsb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v6 }, /* stb d,[rs1+%g0] */ | |
| 695 | +{ "stsb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1), "d,[1+i]", F_ALIAS, v6 }, | |
| 696 | +{ "stsb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1), "d,[i+1]", F_ALIAS, v6 }, | |
| 697 | +{ "stsb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RS1_G0, "d,[i]", F_ALIAS, v6 }, | |
| 698 | +{ "stsb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v6 }, /* stb d,[rs1+0] */ | |
| 699 | +{ "stub", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v6 }, | |
| 700 | +{ "stub", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v6 }, /* stb d,[rs1+%g0] */ | |
| 701 | +{ "stub", F3(3, 0x05, 1), F3(~3, ~0x05, ~1), "d,[1+i]", F_ALIAS, v6 }, | |
| 702 | +{ "stub", F3(3, 0x05, 1), F3(~3, ~0x05, ~1), "d,[i+1]", F_ALIAS, v6 }, | |
| 703 | +{ "stub", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RS1_G0, "d,[i]", F_ALIAS, v6 }, | |
| 704 | +{ "stub", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v6 }, /* stb d,[rs1+0] */ | |
| 705 | + | |
| 706 | +{ "stba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0), "d,[1+2]A", 0, v6 }, | |
| 707 | +{ "stba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0)|RS2(~0), "d,[1]A", 0, v6 }, /* stba d,[rs1+%g0] */ | |
| 708 | +{ "stba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1), "d,[1+i]o", 0, v9 }, | |
| 709 | +{ "stba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1), "d,[i+1]o", 0, v9 }, | |
| 710 | +{ "stba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|RS1_G0, "d,[i]o", 0, v9 }, | |
| 711 | +{ "stba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|SIMM13(~0), "d,[1]o", 0, v9 }, /* stb d,[rs1+0] */ | |
| 712 | + | |
| 713 | +{ "stsba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0), "d,[1+2]A", F_ALIAS, v6 }, | |
| 714 | +{ "stsba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0)|RS2(~0), "d,[1]A", F_ALIAS, v6 }, /* stba d,[rs1+%g0] */ | |
| 715 | +{ "stsba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1), "d,[1+i]o", F_ALIAS, v9 }, | |
| 716 | +{ "stsba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1), "d,[i+1]o", F_ALIAS, v9 }, | |
| 717 | +{ "stsba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|RS1_G0, "d,[i]o", F_ALIAS, v9 }, | |
| 718 | +{ "stsba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|SIMM13(~0), "d,[1]o", F_ALIAS, v9 }, /* stb d,[rs1+0] */ | |
| 719 | +{ "stuba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0), "d,[1+2]A", F_ALIAS, v6 }, | |
| 720 | +{ "stuba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0)|RS2(~0), "d,[1]A", F_ALIAS, v6 }, /* stba d,[rs1+%g0] */ | |
| 721 | +{ "stuba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1), "d,[1+i]o", F_ALIAS, v9 }, | |
| 722 | +{ "stuba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1), "d,[i+1]o", F_ALIAS, v9 }, | |
| 723 | +{ "stuba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|RS1_G0, "d,[i]o", F_ALIAS, v9 }, | |
| 724 | +{ "stuba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|SIMM13(~0), "d,[1]o", F_ALIAS, v9 }, /* stb d,[rs1+0] */ | |
| 725 | + | |
| 726 | +{ "std", F3(3, 0x07, 0), F3(~3, ~0x07, ~0)|ASI(~0), "d,[1+2]", 0, v6 }, | |
| 727 | +{ "std", F3(3, 0x07, 0), F3(~3, ~0x07, ~0)|ASI_RS2(~0), "d,[1]", 0, v6 }, /* std d,[rs1+%g0] */ | |
| 728 | +{ "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1), "d,[1+i]", 0, v6 }, | |
| 729 | +{ "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1), "d,[i+1]", 0, v6 }, | |
| 730 | +{ "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1)|RS1_G0, "d,[i]", 0, v6 }, | |
| 731 | +{ "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1)|SIMM13(~0), "d,[1]", 0, v6 }, /* std d,[rs1+0] */ | |
| 732 | + | |
| 733 | +{ "std", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI(~0), "q,[1+2]", 0, v6notv9 }, | |
| 734 | +{ "std", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI_RS2(~0), "q,[1]", 0, v6notv9 }, /* std d,[rs1+%g0] */ | |
| 735 | +{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "q,[1+i]", 0, v6notv9 }, | |
| 736 | +{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "q,[i+1]", 0, v6notv9 }, | |
| 737 | +{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|RS1_G0, "q,[i]", 0, v6notv9 }, | |
| 738 | +{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|SIMM13(~0), "q,[1]", 0, v6notv9 }, /* std d,[rs1+0] */ | |
| 739 | +{ "std", F3(3, 0x27, 0), F3(~3, ~0x27, ~0)|ASI(~0), "H,[1+2]", 0, v6 }, | |
| 740 | +{ "std", F3(3, 0x27, 0), F3(~3, ~0x27, ~0)|ASI_RS2(~0), "H,[1]", 0, v6 }, /* std d,[rs1+%g0] */ | |
| 741 | +{ "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1), "H,[1+i]", 0, v6 }, | |
| 742 | +{ "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1), "H,[i+1]", 0, v6 }, | |
| 743 | +{ "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1)|RS1_G0, "H,[i]", 0, v6 }, | |
| 744 | +{ "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1)|SIMM13(~0), "H,[1]", 0, v6 }, /* std d,[rs1+0] */ | |
| 745 | + | |
| 746 | +{ "std", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI(~0), "Q,[1+2]", 0, v6notv9 }, | |
| 747 | +{ "std", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI_RS2(~0), "Q,[1]", 0, v6notv9 }, /* std d,[rs1+%g0] */ | |
| 748 | +{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "Q,[1+i]", 0, v6notv9 }, | |
| 749 | +{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "Q,[i+1]", 0, v6notv9 }, | |
| 750 | +{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|RS1_G0, "Q,[i]", 0, v6notv9 }, | |
| 751 | +{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|SIMM13(~0), "Q,[1]", 0, v6notv9 }, /* std d,[rs1+0] */ | |
| 752 | +{ "std", F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|ASI(~0), "D,[1+2]", 0, v6notv9 }, | |
| 753 | +{ "std", F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|ASI_RS2(~0), "D,[1]", 0, v6notv9 }, /* std d,[rs1+%g0] */ | |
| 754 | +{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "D,[1+i]", 0, v6notv9 }, | |
| 755 | +{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "D,[i+1]", 0, v6notv9 }, | |
| 756 | +{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|RS1_G0, "D,[i]", 0, v6notv9 }, | |
| 757 | +{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|SIMM13(~0), "D,[1]", 0, v6notv9 }, /* std d,[rs1+0] */ | |
| 758 | + | |
| 759 | +{ "spilld", F3(3, 0x07, 0), F3(~3, ~0x07, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v6 }, | |
| 760 | +{ "spilld", F3(3, 0x07, 0), F3(~3, ~0x07, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v6 }, /* std d,[rs1+%g0] */ | |
| 761 | +{ "spilld", F3(3, 0x07, 1), F3(~3, ~0x07, ~1), "d,[1+i]", F_ALIAS, v6 }, | |
| 762 | +{ "spilld", F3(3, 0x07, 1), F3(~3, ~0x07, ~1), "d,[i+1]", F_ALIAS, v6 }, | |
| 763 | +{ "spilld", F3(3, 0x07, 1), F3(~3, ~0x07, ~1)|RS1_G0, "d,[i]", F_ALIAS, v6 }, | |
| 764 | +{ "spilld", F3(3, 0x07, 1), F3(~3, ~0x07, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v6 }, /* std d,[rs1+0] */ | |
| 765 | + | |
| 766 | +{ "stda", F3(3, 0x17, 0), F3(~3, ~0x17, ~0), "d,[1+2]A", 0, v6 }, | |
| 767 | +{ "stda", F3(3, 0x17, 0), F3(~3, ~0x17, ~0)|RS2(~0), "d,[1]A", 0, v6 }, /* stda d,[rs1+%g0] */ | |
| 768 | +{ "stda", F3(3, 0x17, 1), F3(~3, ~0x17, ~1), "d,[1+i]o", 0, v9 }, | |
| 769 | +{ "stda", F3(3, 0x17, 1), F3(~3, ~0x17, ~1), "d,[i+1]o", 0, v9 }, | |
| 770 | +{ "stda", F3(3, 0x17, 1), F3(~3, ~0x17, ~1)|RS1_G0, "d,[i]o", 0, v9 }, | |
| 771 | +{ "stda", F3(3, 0x17, 1), F3(~3, ~0x17, ~1)|SIMM13(~0), "d,[1]o", 0, v9 }, /* std d,[rs1+0] */ | |
| 772 | +{ "stda", F3(3, 0x37, 0), F3(~3, ~0x37, ~0), "H,[1+2]A", 0, v9 }, | |
| 773 | +{ "stda", F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|RS2(~0), "H,[1]A", 0, v9 }, /* stda d,[rs1+%g0] */ | |
| 774 | +{ "stda", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "H,[1+i]o", 0, v9 }, | |
| 775 | +{ "stda", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "H,[i+1]o", 0, v9 }, | |
| 776 | +{ "stda", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|RS1_G0, "H,[i]o", 0, v9 }, | |
| 777 | +{ "stda", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|SIMM13(~0), "H,[1]o", 0, v9 }, /* std d,[rs1+0] */ | |
| 778 | + | |
| 779 | +{ "sth", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|ASI(~0), "d,[1+2]", 0, v6 }, | |
| 780 | +{ "sth", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|ASI_RS2(~0), "d,[1]", 0, v6 }, /* sth d,[rs1+%g0] */ | |
| 781 | +{ "sth", F3(3, 0x06, 1), F3(~3, ~0x06, ~1), "d,[1+i]", 0, v6 }, | |
| 782 | +{ "sth", F3(3, 0x06, 1), F3(~3, ~0x06, ~1), "d,[i+1]", 0, v6 }, | |
| 783 | +{ "sth", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RS1_G0, "d,[i]", 0, v6 }, | |
| 784 | +{ "sth", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|SIMM13(~0), "d,[1]", 0, v6 }, /* sth d,[rs1+0] */ | |
| 785 | + | |
| 786 | +{ "stsh", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v6 }, | |
| 787 | +{ "stsh", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v6 }, /* sth d,[rs1+%g0] */ | |
| 788 | +{ "stsh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1), "d,[1+i]", F_ALIAS, v6 }, | |
| 789 | +{ "stsh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1), "d,[i+1]", F_ALIAS, v6 }, | |
| 790 | +{ "stsh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RS1_G0, "d,[i]", F_ALIAS, v6 }, | |
| 791 | +{ "stsh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v6 }, /* sth d,[rs1+0] */ | |
| 792 | +{ "stuh", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v6 }, | |
| 793 | +{ "stuh", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v6 }, /* sth d,[rs1+%g0] */ | |
| 794 | +{ "stuh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1), "d,[1+i]", F_ALIAS, v6 }, | |
| 795 | +{ "stuh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1), "d,[i+1]", F_ALIAS, v6 }, | |
| 796 | +{ "stuh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RS1_G0, "d,[i]", F_ALIAS, v6 }, | |
| 797 | +{ "stuh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v6 }, /* sth d,[rs1+0] */ | |
| 798 | + | |
| 799 | +{ "stha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0), "d,[1+2]A", 0, v6 }, | |
| 800 | +{ "stha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0)|RS2(~0), "d,[1]A", 0, v6 }, /* stha ,[rs1+%g0] */ | |
| 801 | +{ "stha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1), "d,[1+i]o", 0, v9 }, | |
| 802 | +{ "stha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1), "d,[i+1]o", 0, v9 }, | |
| 803 | +{ "stha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|RS1_G0, "d,[i]o", 0, v9 }, | |
| 804 | +{ "stha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|SIMM13(~0), "d,[1]o", 0, v9 }, /* sth d,[rs1+0] */ | |
| 805 | + | |
| 806 | +{ "stsha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0), "d,[1+2]A", F_ALIAS, v6 }, | |
| 807 | +{ "stsha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0)|RS2(~0), "d,[1]A", F_ALIAS, v6 }, /* stha ,[rs1+%g0] */ | |
| 808 | +{ "stsha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1), "d,[1+i]o", F_ALIAS, v9 }, | |
| 809 | +{ "stsha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1), "d,[i+1]o", F_ALIAS, v9 }, | |
| 810 | +{ "stsha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|RS1_G0, "d,[i]o", F_ALIAS, v9 }, | |
| 811 | +{ "stsha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|SIMM13(~0), "d,[1]o", F_ALIAS, v9 }, /* sth d,[rs1+0] */ | |
| 812 | +{ "stuha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0), "d,[1+2]A", F_ALIAS, v6 }, | |
| 813 | +{ "stuha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0)|RS2(~0), "d,[1]A", F_ALIAS, v6 }, /* stha ,[rs1+%g0] */ | |
| 814 | +{ "stuha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1), "d,[1+i]o", F_ALIAS, v9 }, | |
| 815 | +{ "stuha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1), "d,[i+1]o", F_ALIAS, v9 }, | |
| 816 | +{ "stuha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|RS1_G0, "d,[i]o", F_ALIAS, v9 }, | |
| 817 | +{ "stuha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|SIMM13(~0), "d,[1]o", F_ALIAS, v9 }, /* sth d,[rs1+0] */ | |
| 818 | + | |
| 819 | +{ "stx", F3(3, 0x0e, 0), F3(~3, ~0x0e, ~0)|ASI(~0), "d,[1+2]", 0, v9 }, | |
| 820 | +{ "stx", F3(3, 0x0e, 0), F3(~3, ~0x0e, ~0)|ASI_RS2(~0), "d,[1]", 0, v9 }, /* stx d,[rs1+%g0] */ | |
| 821 | +{ "stx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1), "d,[1+i]", 0, v9 }, | |
| 822 | +{ "stx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1), "d,[i+1]", 0, v9 }, | |
| 823 | +{ "stx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|RS1_G0, "d,[i]", 0, v9 }, | |
| 824 | +{ "stx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|SIMM13(~0), "d,[1]", 0, v9 }, /* stx d,[rs1+0] */ | |
| 825 | + | |
| 826 | +{ "stx", F3(3, 0x25, 0)|RD(1), F3(~3, ~0x25, ~0)|ASI(~0)|RD(~1), "F,[1+2]", 0, v9 }, | |
| 827 | +{ "stx", F3(3, 0x25, 0)|RD(1), F3(~3, ~0x25, ~0)|ASI_RS2(~0)|RD(~1),"F,[1]", 0, v9 }, /* stx d,[rs1+%g0] */ | |
| 828 | +{ "stx", F3(3, 0x25, 1)|RD(1), F3(~3, ~0x25, ~1)|RD(~1), "F,[1+i]", 0, v9 }, | |
| 829 | +{ "stx", F3(3, 0x25, 1)|RD(1), F3(~3, ~0x25, ~1)|RD(~1), "F,[i+1]", 0, v9 }, | |
| 830 | +{ "stx", F3(3, 0x25, 1)|RD(1), F3(~3, ~0x25, ~1)|RS1_G0|RD(~1), "F,[i]", 0, v9 }, | |
| 831 | +{ "stx", F3(3, 0x25, 1)|RD(1), F3(~3, ~0x25, ~1)|SIMM13(~0)|RD(~1),"F,[1]", 0, v9 }, /* stx d,[rs1+0] */ | |
| 832 | + | |
| 833 | +{ "stxa", F3(3, 0x1e, 0), F3(~3, ~0x1e, ~0), "d,[1+2]A", 0, v9 }, | |
| 834 | +{ "stxa", F3(3, 0x1e, 0), F3(~3, ~0x1e, ~0)|RS2(~0), "d,[1]A", 0, v9 }, /* stxa d,[rs1+%g0] */ | |
| 835 | +{ "stxa", F3(3, 0x1e, 1), F3(~3, ~0x1e, ~1), "d,[1+i]o", 0, v9 }, | |
| 836 | +{ "stxa", F3(3, 0x1e, 1), F3(~3, ~0x1e, ~1), "d,[i+1]o", 0, v9 }, | |
| 837 | +{ "stxa", F3(3, 0x1e, 1), F3(~3, ~0x1e, ~1)|RS1_G0, "d,[i]o", 0, v9 }, | |
| 838 | +{ "stxa", F3(3, 0x1e, 1), F3(~3, ~0x1e, ~1)|SIMM13(~0), "d,[1]o", 0, v9 }, /* stx d,[rs1+0] */ | |
| 839 | + | |
| 840 | +{ "stq", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI(~0), "J,[1+2]", 0, v9 }, | |
| 841 | +{ "stq", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI_RS2(~0), "J,[1]", 0, v9 }, /* stq [rs1+%g0] */ | |
| 842 | +{ "stq", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "J,[1+i]", 0, v9 }, | |
| 843 | +{ "stq", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "J,[i+1]", 0, v9 }, | |
| 844 | +{ "stq", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|RS1_G0, "J,[i]", 0, v9 }, | |
| 845 | +{ "stq", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|SIMM13(~0), "J,[1]", 0, v9 }, /* stq [rs1+0] */ | |
| 846 | + | |
| 847 | +{ "stqa", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI(~0), "J,[1+2]A", 0, v9 }, | |
| 848 | +{ "stqa", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI_RS2(~0), "J,[1]A", 0, v9 }, /* stqa [rs1+%g0] */ | |
| 849 | +{ "stqa", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "J,[1+i]o", 0, v9 }, | |
| 850 | +{ "stqa", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "J,[i+1]o", 0, v9 }, | |
| 851 | +{ "stqa", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|RS1_G0, "J,[i]o", 0, v9 }, | |
| 852 | +{ "stqa", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|SIMM13(~0), "J,[1]o", 0, v9 }, /* stqa [rs1+0] */ | |
| 853 | + | |
| 854 | +{ "swap", F3(3, 0x0f, 0), F3(~3, ~0x0f, ~0)|ASI(~0), "[1+2],d", 0, v7 }, | |
| 855 | +{ "swap", F3(3, 0x0f, 0), F3(~3, ~0x0f, ~0)|ASI_RS2(~0), "[1],d", 0, v7 }, /* swap [rs1+%g0],d */ | |
| 856 | +{ "swap", F3(3, 0x0f, 1), F3(~3, ~0x0f, ~1), "[1+i],d", 0, v7 }, | |
| 857 | +{ "swap", F3(3, 0x0f, 1), F3(~3, ~0x0f, ~1), "[i+1],d", 0, v7 }, | |
| 858 | +{ "swap", F3(3, 0x0f, 1), F3(~3, ~0x0f, ~1)|RS1_G0, "[i],d", 0, v7 }, | |
| 859 | +{ "swap", F3(3, 0x0f, 1), F3(~3, ~0x0f, ~1)|SIMM13(~0), "[1],d", 0, v7 }, /* swap [rs1+0],d */ | |
| 860 | + | |
| 861 | +{ "swapa", F3(3, 0x1f, 0), F3(~3, ~0x1f, ~0), "[1+2]A,d", 0, v7 }, | |
| 862 | +{ "swapa", F3(3, 0x1f, 0), F3(~3, ~0x1f, ~0)|RS2(~0), "[1]A,d", 0, v7 }, /* swapa [rs1+%g0],d */ | |
| 863 | +{ "swapa", F3(3, 0x1f, 1), F3(~3, ~0x1f, ~1), "[1+i]o,d", 0, v9 }, | |
| 864 | +{ "swapa", F3(3, 0x1f, 1), F3(~3, ~0x1f, ~1), "[i+1]o,d", 0, v9 }, | |
| 865 | +{ "swapa", F3(3, 0x1f, 1), F3(~3, ~0x1f, ~1)|RS1_G0, "[i]o,d", 0, v9 }, | |
| 866 | +{ "swapa", F3(3, 0x1f, 1), F3(~3, ~0x1f, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* swap [rs1+0],d */ | |
| 867 | + | |
| 868 | +{ "restore", F3(2, 0x3d, 0), F3(~2, ~0x3d, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 869 | +{ "restore", F3(2, 0x3d, 0), F3(~2, ~0x3d, ~0)|RD_G0|RS1_G0|ASI_RS2(~0), "", 0, v6 }, /* restore %g0,%g0,%g0 */ | |
| 870 | +{ "restore", F3(2, 0x3d, 1), F3(~2, ~0x3d, ~1), "1,i,d", 0, v6 }, | |
| 871 | +{ "restore", F3(2, 0x3d, 1), F3(~2, ~0x3d, ~1)|RD_G0|RS1_G0|SIMM13(~0), "", 0, v6 }, /* restore %g0,0,%g0 */ | |
| 872 | + | |
| 873 | +{ "rett", F3(2, 0x39, 0), F3(~2, ~0x39, ~0)|RD_G0|ASI(~0), "1+2", F_UNBR|F_DELAYED, v6 }, /* rett rs1+rs2 */ | |
| 874 | +{ "rett", F3(2, 0x39, 0), F3(~2, ~0x39, ~0)|RD_G0|ASI_RS2(~0), "1", F_UNBR|F_DELAYED, v6 }, /* rett rs1,%g0 */ | |
| 875 | +{ "rett", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RD_G0, "1+i", F_UNBR|F_DELAYED, v6 }, /* rett rs1+X */ | |
| 876 | +{ "rett", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RD_G0, "i+1", F_UNBR|F_DELAYED, v6 }, /* rett X+rs1 */ | |
| 877 | +{ "rett", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RD_G0|RS1_G0, "i", F_UNBR|F_DELAYED, v6 }, /* rett X+rs1 */ | |
| 878 | +{ "rett", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RD_G0|RS1_G0, "i", F_UNBR|F_DELAYED, v6 }, /* rett X */ | |
| 879 | +{ "rett", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RD_G0|SIMM13(~0), "1", F_UNBR|F_DELAYED, v6 }, /* rett rs1+0 */ | |
| 880 | + | |
| 881 | +{ "save", F3(2, 0x3c, 0), F3(~2, ~0x3c, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 882 | +{ "save", F3(2, 0x3c, 1), F3(~2, ~0x3c, ~1), "1,i,d", 0, v6 }, | |
| 883 | +{ "save", 0x81e00000, ~0x81e00000, "", F_ALIAS, v6 }, | |
| 884 | + | |
| 885 | +{ "ret", F3(2, 0x38, 1)|RS1(0x1f)|SIMM13(8), F3(~2, ~0x38, ~1)|SIMM13(~8), "", F_UNBR|F_DELAYED, v6 }, /* jmpl %i7+8,%g0 */ | |
| 886 | +{ "retl", F3(2, 0x38, 1)|RS1(0x0f)|SIMM13(8), F3(~2, ~0x38, ~1)|RS1(~0x0f)|SIMM13(~8), "", F_UNBR|F_DELAYED, v6 }, /* jmpl %o7+8,%g0 */ | |
| 887 | + | |
| 888 | +{ "jmpl", F3(2, 0x38, 0), F3(~2, ~0x38, ~0)|ASI(~0), "1+2,d", F_JSR|F_DELAYED, v6 }, | |
| 889 | +{ "jmpl", F3(2, 0x38, 0), F3(~2, ~0x38, ~0)|ASI_RS2(~0), "1,d", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+%g0,d */ | |
| 890 | +{ "jmpl", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|SIMM13(~0), "1,d", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+0,d */ | |
| 891 | +{ "jmpl", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|RS1_G0, "i,d", F_JSR|F_DELAYED, v6 }, /* jmpl %g0+i,d */ | |
| 892 | +{ "jmpl", F3(2, 0x38, 1), F3(~2, ~0x38, ~1), "1+i,d", F_JSR|F_DELAYED, v6 }, | |
| 893 | +{ "jmpl", F3(2, 0x38, 1), F3(~2, ~0x38, ~1), "i+1,d", F_JSR|F_DELAYED, v6 }, | |
| 894 | + | |
| 895 | +{ "done", F3(2, 0x3e, 0)|RD(0), F3(~2, ~0x3e, ~0)|RD(~0)|RS1_G0|SIMM13(~0), "", 0, v9 }, | |
| 896 | +{ "retry", F3(2, 0x3e, 0)|RD(1), F3(~2, ~0x3e, ~0)|RD(~1)|RS1_G0|SIMM13(~0), "", 0, v9 }, | |
| 897 | +{ "saved", F3(2, 0x31, 0)|RD(0), F3(~2, ~0x31, ~0)|RD(~0)|RS1_G0|SIMM13(~0), "", 0, v9 }, | |
| 898 | +{ "restored", F3(2, 0x31, 0)|RD(1), F3(~2, ~0x31, ~0)|RD(~1)|RS1_G0|SIMM13(~0), "", 0, v9 }, | |
| 899 | +{ "sir", F3(2, 0x30, 1)|RD(0xf), F3(~2, ~0x30, ~1)|RD(~0xf)|RS1_G0, "i", 0, v9 }, | |
| 900 | + | |
| 901 | +{ "flush", F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI(~0), "1+2", 0, v8 }, | |
| 902 | +{ "flush", F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI_RS2(~0), "1", 0, v8 }, /* flush rs1+%g0 */ | |
| 903 | +{ "flush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1)|SIMM13(~0), "1", 0, v8 }, /* flush rs1+0 */ | |
| 904 | +{ "flush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1)|RS1_G0, "i", 0, v8 }, /* flush %g0+i */ | |
| 905 | +{ "flush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1), "1+i", 0, v8 }, | |
| 906 | +{ "flush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1), "i+1", 0, v8 }, | |
| 907 | + | |
| 908 | +/* IFLUSH was renamed to FLUSH in v8. */ | |
| 909 | +{ "iflush", F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI(~0), "1+2", F_ALIAS, v6 }, | |
| 910 | +{ "iflush", F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI_RS2(~0), "1", F_ALIAS, v6 }, /* flush rs1+%g0 */ | |
| 911 | +{ "iflush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1)|SIMM13(~0), "1", F_ALIAS, v6 }, /* flush rs1+0 */ | |
| 912 | +{ "iflush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1)|RS1_G0, "i", F_ALIAS, v6 }, | |
| 913 | +{ "iflush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1), "1+i", F_ALIAS, v6 }, | |
| 914 | +{ "iflush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1), "i+1", F_ALIAS, v6 }, | |
| 915 | + | |
| 916 | +{ "return", F3(2, 0x39, 0), F3(~2, ~0x39, ~0)|ASI(~0), "1+2", 0, v9 }, | |
| 917 | +{ "return", F3(2, 0x39, 0), F3(~2, ~0x39, ~0)|ASI_RS2(~0), "1", 0, v9 }, /* return rs1+%g0 */ | |
| 918 | +{ "return", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|SIMM13(~0), "1", 0, v9 }, /* return rs1+0 */ | |
| 919 | +{ "return", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RS1_G0, "i", 0, v9 }, /* return %g0+i */ | |
| 920 | +{ "return", F3(2, 0x39, 1), F3(~2, ~0x39, ~1), "1+i", 0, v9 }, | |
| 921 | +{ "return", F3(2, 0x39, 1), F3(~2, ~0x39, ~1), "i+1", 0, v9 }, | |
| 922 | + | |
| 923 | +{ "flushw", F3(2, 0x2b, 0), F3(~2, ~0x2b, ~0)|RD_G0|RS1_G0|ASI_RS2(~0), "", 0, v9 }, | |
| 924 | + | |
| 925 | +{ "membar", F3(2, 0x28, 1)|RS1(0xf), F3(~2, ~0x28, ~1)|RD_G0|RS1(~0xf)|SIMM13(~127), "K", 0, v9 }, | |
| 926 | +{ "stbar", F3(2, 0x28, 0)|RS1(0xf), F3(~2, ~0x28, ~0)|RD_G0|RS1(~0xf)|SIMM13(~0), "", 0, v8 }, | |
| 927 | + | |
| 928 | +{ "prefetch", F3(3, 0x2d, 0), F3(~3, ~0x2d, ~0), "[1+2],*", 0, v9 }, | |
| 929 | +{ "prefetch", F3(3, 0x2d, 0), F3(~3, ~0x2d, ~0)|RS2_G0, "[1],*", 0, v9 }, /* prefetch [rs1+%g0],prefetch_fcn */ | |
| 930 | +{ "prefetch", F3(3, 0x2d, 1), F3(~3, ~0x2d, ~1), "[1+i],*", 0, v9 }, | |
| 931 | +{ "prefetch", F3(3, 0x2d, 1), F3(~3, ~0x2d, ~1), "[i+1],*", 0, v9 }, | |
| 932 | +{ "prefetch", F3(3, 0x2d, 1), F3(~3, ~0x2d, ~1)|RS1_G0, "[i],*", 0, v9 }, | |
| 933 | +{ "prefetch", F3(3, 0x2d, 1), F3(~3, ~0x2d, ~1)|SIMM13(~0), "[1],*", 0, v9 }, /* prefetch [rs1+0],prefetch_fcn */ | |
| 934 | +{ "prefetcha", F3(3, 0x3d, 0), F3(~3, ~0x3d, ~0), "[1+2]A,*", 0, v9 }, | |
| 935 | +{ "prefetcha", F3(3, 0x3d, 0), F3(~3, ~0x3d, ~0)|RS2_G0, "[1]A,*", 0, v9 }, /* prefetcha [rs1+%g0],prefetch_fcn */ | |
| 936 | +{ "prefetcha", F3(3, 0x3d, 1), F3(~3, ~0x3d, ~1), "[1+i]o,*", 0, v9 }, | |
| 937 | +{ "prefetcha", F3(3, 0x3d, 1), F3(~3, ~0x3d, ~1), "[i+1]o,*", 0, v9 }, | |
| 938 | +{ "prefetcha", F3(3, 0x3d, 1), F3(~3, ~0x3d, ~1)|RS1_G0, "[i]o,*", 0, v9 }, | |
| 939 | +{ "prefetcha", F3(3, 0x3d, 1), F3(~3, ~0x3d, ~1)|SIMM13(~0), "[1]o,*", 0, v9 }, /* prefetcha [rs1+0],d */ | |
| 940 | + | |
| 941 | +{ "sll", F3(2, 0x25, 0), F3(~2, ~0x25, ~0)|(1<<12)|(0x7f<<5), "1,2,d", 0, v6 }, | |
| 942 | +{ "sll", F3(2, 0x25, 1), F3(~2, ~0x25, ~1)|(1<<12)|(0x7f<<5), "1,X,d", 0, v6 }, | |
| 943 | +{ "sra", F3(2, 0x27, 0), F3(~2, ~0x27, ~0)|(1<<12)|(0x7f<<5), "1,2,d", 0, v6 }, | |
| 944 | +{ "sra", F3(2, 0x27, 1), F3(~2, ~0x27, ~1)|(1<<12)|(0x7f<<5), "1,X,d", 0, v6 }, | |
| 945 | +{ "srl", F3(2, 0x26, 0), F3(~2, ~0x26, ~0)|(1<<12)|(0x7f<<5), "1,2,d", 0, v6 }, | |
| 946 | +{ "srl", F3(2, 0x26, 1), F3(~2, ~0x26, ~1)|(1<<12)|(0x7f<<5), "1,X,d", 0, v6 }, | |
| 947 | + | |
| 948 | +{ "sllx", F3(2, 0x25, 0)|(1<<12), F3(~2, ~0x25, ~0)|(0x7f<<5), "1,2,d", 0, v9 }, | |
| 949 | +{ "sllx", F3(2, 0x25, 1)|(1<<12), F3(~2, ~0x25, ~1)|(0x3f<<6), "1,Y,d", 0, v9 }, | |
| 950 | +{ "srax", F3(2, 0x27, 0)|(1<<12), F3(~2, ~0x27, ~0)|(0x7f<<5), "1,2,d", 0, v9 }, | |
| 951 | +{ "srax", F3(2, 0x27, 1)|(1<<12), F3(~2, ~0x27, ~1)|(0x3f<<6), "1,Y,d", 0, v9 }, | |
| 952 | +{ "srlx", F3(2, 0x26, 0)|(1<<12), F3(~2, ~0x26, ~0)|(0x7f<<5), "1,2,d", 0, v9 }, | |
| 953 | +{ "srlx", F3(2, 0x26, 1)|(1<<12), F3(~2, ~0x26, ~1)|(0x3f<<6), "1,Y,d", 0, v9 }, | |
| 954 | + | |
| 955 | +{ "mulscc", F3(2, 0x24, 0), F3(~2, ~0x24, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 956 | +{ "mulscc", F3(2, 0x24, 1), F3(~2, ~0x24, ~1), "1,i,d", 0, v6 }, | |
| 957 | + | |
| 958 | +{ "divscc", F3(2, 0x1d, 0), F3(~2, ~0x1d, ~0)|ASI(~0), "1,2,d", 0, sparclite }, | |
| 959 | +{ "divscc", F3(2, 0x1d, 1), F3(~2, ~0x1d, ~1), "1,i,d", 0, sparclite }, | |
| 960 | + | |
| 961 | +{ "scan", F3(2, 0x2c, 0), F3(~2, ~0x2c, ~0)|ASI(~0), "1,2,d", 0, sparclet|sparclite }, | |
| 962 | +{ "scan", F3(2, 0x2c, 1), F3(~2, ~0x2c, ~1), "1,i,d", 0, sparclet|sparclite }, | |
| 963 | + | |
| 964 | +{ "popc", F3(2, 0x2e, 0), F3(~2, ~0x2e, ~0)|RS1_G0|ASI(~0),"2,d", 0, v9 }, | |
| 965 | +{ "popc", F3(2, 0x2e, 1), F3(~2, ~0x2e, ~1)|RS1_G0, "i,d", 0, v9 }, | |
| 966 | + | |
| 967 | +{ "clr", F3(2, 0x02, 0), F3(~2, ~0x02, ~0)|RD_G0|RS1_G0|ASI_RS2(~0), "d", F_ALIAS, v6 }, /* or %g0,%g0,d */ | |
| 968 | +{ "clr", F3(2, 0x02, 1), F3(~2, ~0x02, ~1)|RS1_G0|SIMM13(~0), "d", F_ALIAS, v6 }, /* or %g0,0,d */ | |
| 969 | +{ "clr", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|RD_G0|ASI(~0), "[1+2]", F_ALIAS, v6 }, | |
| 970 | +{ "clr", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|RD_G0|ASI_RS2(~0), "[1]", F_ALIAS, v6 }, /* st %g0,[rs1+%g0] */ | |
| 971 | +{ "clr", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RD_G0, "[1+i]", F_ALIAS, v6 }, | |
| 972 | +{ "clr", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RD_G0, "[i+1]", F_ALIAS, v6 }, | |
| 973 | +{ "clr", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RD_G0|RS1_G0, "[i]", F_ALIAS, v6 }, | |
| 974 | +{ "clr", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RD_G0|SIMM13(~0), "[1]", F_ALIAS, v6 }, /* st %g0,[rs1+0] */ | |
| 975 | + | |
| 976 | +{ "clrb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|RD_G0|ASI(~0), "[1+2]", F_ALIAS, v6 }, | |
| 977 | +{ "clrb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|RD_G0|ASI_RS2(~0), "[1]", F_ALIAS, v6 }, /* stb %g0,[rs1+%g0] */ | |
| 978 | +{ "clrb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RD_G0, "[1+i]", F_ALIAS, v6 }, | |
| 979 | +{ "clrb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RD_G0, "[i+1]", F_ALIAS, v6 }, | |
| 980 | +{ "clrb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RD_G0|RS1_G0, "[i]", F_ALIAS, v6 }, | |
| 981 | +{ "clrb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RD_G0|SIMM13(~0), "[1]", F_ALIAS, v6 }, /* stb %g0,[rs1+0] */ | |
| 982 | + | |
| 983 | +{ "clrh", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|RD_G0|ASI(~0), "[1+2]", F_ALIAS, v6 }, | |
| 984 | +{ "clrh", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|RD_G0|ASI_RS2(~0), "[1]", F_ALIAS, v6 }, /* sth %g0,[rs1+%g0] */ | |
| 985 | +{ "clrh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RD_G0, "[1+i]", F_ALIAS, v6 }, | |
| 986 | +{ "clrh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RD_G0, "[i+1]", F_ALIAS, v6 }, | |
| 987 | +{ "clrh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RD_G0|RS1_G0, "[i]", F_ALIAS, v6 }, | |
| 988 | +{ "clrh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RD_G0|SIMM13(~0), "[1]", F_ALIAS, v6 }, /* sth %g0,[rs1+0] */ | |
| 989 | + | |
| 990 | +{ "clrx", F3(3, 0x0e, 0), F3(~3, ~0x0e, ~0)|RD_G0|ASI(~0), "[1+2]", F_ALIAS, v9 }, | |
| 991 | +{ "clrx", F3(3, 0x0e, 0), F3(~3, ~0x0e, ~0)|RD_G0|ASI_RS2(~0), "[1]", F_ALIAS, v9 }, /* stx %g0,[rs1+%g0] */ | |
| 992 | +{ "clrx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|RD_G0, "[1+i]", F_ALIAS, v9 }, | |
| 993 | +{ "clrx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|RD_G0, "[i+1]", F_ALIAS, v9 }, | |
| 994 | +{ "clrx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|RD_G0|RS1_G0, "[i]", F_ALIAS, v9 }, | |
| 995 | +{ "clrx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|RD_G0|SIMM13(~0), "[1]", F_ALIAS, v9 }, /* stx %g0,[rs1+0] */ | |
| 996 | + | |
| 997 | +{ "orcc", F3(2, 0x12, 0), F3(~2, ~0x12, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 998 | +{ "orcc", F3(2, 0x12, 1), F3(~2, ~0x12, ~1), "1,i,d", 0, v6 }, | |
| 999 | +{ "orcc", F3(2, 0x12, 1), F3(~2, ~0x12, ~1), "i,1,d", 0, v6 }, | |
| 1000 | + | |
| 1001 | +/* This is not a commutative instruction. */ | |
| 1002 | +{ "orncc", F3(2, 0x16, 0), F3(~2, ~0x16, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1003 | +{ "orncc", F3(2, 0x16, 1), F3(~2, ~0x16, ~1), "1,i,d", 0, v6 }, | |
| 1004 | + | |
| 1005 | +/* This is not a commutative instruction. */ | |
| 1006 | +{ "orn", F3(2, 0x06, 0), F3(~2, ~0x06, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1007 | +{ "orn", F3(2, 0x06, 1), F3(~2, ~0x06, ~1), "1,i,d", 0, v6 }, | |
| 1008 | + | |
| 1009 | +{ "tst", F3(2, 0x12, 0), F3(~2, ~0x12, ~0)|RD_G0|ASI_RS2(~0), "1", 0, v6 }, /* orcc rs1, %g0, %g0 */ | |
| 1010 | +{ "tst", F3(2, 0x12, 0), F3(~2, ~0x12, ~0)|RD_G0|RS1_G0|ASI(~0), "2", 0, v6 }, /* orcc %g0, rs2, %g0 */ | |
| 1011 | +{ "tst", F3(2, 0x12, 1), F3(~2, ~0x12, ~1)|RD_G0|SIMM13(~0), "1", 0, v6 }, /* orcc rs1, 0, %g0 */ | |
| 1012 | + | |
| 1013 | +{ "wr", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|ASI(~0), "1,2,m", 0, v8 }, /* wr r,r,%asrX */ | |
| 1014 | +{ "wr", F3(2, 0x30, 1), F3(~2, ~0x30, ~1), "1,i,m", 0, v8 }, /* wr r,i,%asrX */ | |
| 1015 | +{ "wr", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|ASI_RS2(~0), "1,m", F_ALIAS, v8 }, /* wr rs1,%g0,%asrX */ | |
| 1016 | +{ "wr", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|RD_G0|ASI(~0), "1,2,y", 0, v6 }, /* wr r,r,%y */ | |
| 1017 | +{ "wr", F3(2, 0x30, 1), F3(~2, ~0x30, ~1)|RD_G0, "1,i,y", 0, v6 }, /* wr r,i,%y */ | |
| 1018 | +{ "wr", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|RD_G0|ASI_RS2(~0), "1,y", F_ALIAS, v6 }, /* wr rs1,%g0,%y */ | |
| 1019 | +{ "wr", F3(2, 0x31, 0), F3(~2, ~0x31, ~0)|RD_G0|ASI(~0), "1,2,p", 0, v6notv9 }, /* wr r,r,%psr */ | |
| 1020 | +{ "wr", F3(2, 0x31, 1), F3(~2, ~0x31, ~1)|RD_G0, "1,i,p", 0, v6notv9 }, /* wr r,i,%psr */ | |
| 1021 | +{ "wr", F3(2, 0x31, 0), F3(~2, ~0x31, ~0)|RD_G0|ASI_RS2(~0), "1,p", F_ALIAS, v6notv9 }, /* wr rs1,%g0,%psr */ | |
| 1022 | +{ "wr", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|RD_G0|ASI(~0), "1,2,w", 0, v6notv9 }, /* wr r,r,%wim */ | |
| 1023 | +{ "wr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RD_G0, "1,i,w", 0, v6notv9 }, /* wr r,i,%wim */ | |
| 1024 | +{ "wr", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|RD_G0|ASI_RS2(~0), "1,w", F_ALIAS, v6notv9 }, /* wr rs1,%g0,%wim */ | |
| 1025 | +{ "wr", F3(2, 0x33, 0), F3(~2, ~0x33, ~0)|RD_G0|ASI(~0), "1,2,t", 0, v6notv9 }, /* wr r,r,%tbr */ | |
| 1026 | +{ "wr", F3(2, 0x33, 1), F3(~2, ~0x33, ~1)|RD_G0, "1,i,t", 0, v6notv9 }, /* wr r,i,%tbr */ | |
| 1027 | +{ "wr", F3(2, 0x33, 0), F3(~2, ~0x33, ~0)|RD_G0|ASI_RS2(~0), "1,t", F_ALIAS, v6notv9 }, /* wr rs1,%g0,%tbr */ | |
| 1028 | + | |
| 1029 | +{ "wr", F3(2, 0x30, 0)|RD(2), F3(~2, ~0x30, ~0)|RD(~2)|ASI(~0), "1,2,E", 0, v9 }, /* wr r,r,%ccr */ | |
| 1030 | +{ "wr", F3(2, 0x30, 1)|RD(2), F3(~2, ~0x30, ~1)|RD(~2), "1,i,E", 0, v9 }, /* wr r,i,%ccr */ | |
| 1031 | +{ "wr", F3(2, 0x30, 0)|RD(3), F3(~2, ~0x30, ~0)|RD(~3)|ASI(~0), "1,2,o", 0, v9 }, /* wr r,r,%asi */ | |
| 1032 | +{ "wr", F3(2, 0x30, 1)|RD(3), F3(~2, ~0x30, ~1)|RD(~3), "1,i,o", 0, v9 }, /* wr r,i,%asi */ | |
| 1033 | +{ "wr", F3(2, 0x30, 0)|RD(6), F3(~2, ~0x30, ~0)|RD(~6)|ASI(~0), "1,2,s", 0, v9 }, /* wr r,r,%fprs */ | |
| 1034 | +{ "wr", F3(2, 0x30, 1)|RD(6), F3(~2, ~0x30, ~1)|RD(~6), "1,i,s", 0, v9 }, /* wr r,i,%fprs */ | |
| 1035 | + | |
| 1036 | +{ "wr", F3(2, 0x30, 0)|RD(16), F3(~2, ~0x30, ~0)|RD(~16)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%pcr */ | |
| 1037 | +{ "wr", F3(2, 0x30, 1)|RD(16), F3(~2, ~0x30, ~1)|RD(~16), "1,i,_", 0, v9a }, /* wr r,i,%pcr */ | |
| 1038 | +{ "wr", F3(2, 0x30, 0)|RD(17), F3(~2, ~0x30, ~0)|RD(~17)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%pic */ | |
| 1039 | +{ "wr", F3(2, 0x30, 1)|RD(17), F3(~2, ~0x30, ~1)|RD(~17), "1,i,_", 0, v9a }, /* wr r,i,%pic */ | |
| 1040 | +{ "wr", F3(2, 0x30, 0)|RD(18), F3(~2, ~0x30, ~0)|RD(~18)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%dcr */ | |
| 1041 | +{ "wr", F3(2, 0x30, 1)|RD(18), F3(~2, ~0x30, ~1)|RD(~18), "1,i,_", 0, v9a }, /* wr r,i,%dcr */ | |
| 1042 | +{ "wr", F3(2, 0x30, 0)|RD(19), F3(~2, ~0x30, ~0)|RD(~19)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%gsr */ | |
| 1043 | +{ "wr", F3(2, 0x30, 1)|RD(19), F3(~2, ~0x30, ~1)|RD(~19), "1,i,_", 0, v9a }, /* wr r,i,%gsr */ | |
| 1044 | +{ "wr", F3(2, 0x30, 0)|RD(20), F3(~2, ~0x30, ~0)|RD(~20)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%set_softint */ | |
| 1045 | +{ "wr", F3(2, 0x30, 1)|RD(20), F3(~2, ~0x30, ~1)|RD(~20), "1,i,_", 0, v9a }, /* wr r,i,%set_softint */ | |
| 1046 | +{ "wr", F3(2, 0x30, 0)|RD(21), F3(~2, ~0x30, ~0)|RD(~21)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%clear_softint */ | |
| 1047 | +{ "wr", F3(2, 0x30, 1)|RD(21), F3(~2, ~0x30, ~1)|RD(~21), "1,i,_", 0, v9a }, /* wr r,i,%clear_softint */ | |
| 1048 | +{ "wr", F3(2, 0x30, 0)|RD(22), F3(~2, ~0x30, ~0)|RD(~22)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%softint */ | |
| 1049 | +{ "wr", F3(2, 0x30, 1)|RD(22), F3(~2, ~0x30, ~1)|RD(~22), "1,i,_", 0, v9a }, /* wr r,i,%softint */ | |
| 1050 | +{ "wr", F3(2, 0x30, 0)|RD(23), F3(~2, ~0x30, ~0)|RD(~23)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%tick_cmpr */ | |
| 1051 | +{ "wr", F3(2, 0x30, 1)|RD(23), F3(~2, ~0x30, ~1)|RD(~23), "1,i,_", 0, v9a }, /* wr r,i,%tick_cmpr */ | |
| 1052 | +{ "wr", F3(2, 0x30, 0)|RD(24), F3(~2, ~0x30, ~0)|RD(~24)|ASI(~0), "1,2,_", 0, v9b }, /* wr r,r,%sys_tick */ | |
| 1053 | +{ "wr", F3(2, 0x30, 1)|RD(24), F3(~2, ~0x30, ~1)|RD(~24), "1,i,_", 0, v9b }, /* wr r,i,%sys_tick */ | |
| 1054 | +{ "wr", F3(2, 0x30, 0)|RD(25), F3(~2, ~0x30, ~0)|RD(~25)|ASI(~0), "1,2,_", 0, v9b }, /* wr r,r,%sys_tick_cmpr */ | |
| 1055 | +{ "wr", F3(2, 0x30, 1)|RD(25), F3(~2, ~0x30, ~1)|RD(~25), "1,i,_", 0, v9b }, /* wr r,i,%sys_tick_cmpr */ | |
| 1056 | + | |
| 1057 | +{ "rd", F3(2, 0x28, 0), F3(~2, ~0x28, ~0)|SIMM13(~0), "M,d", 0, v8 }, /* rd %asrX,r */ | |
| 1058 | +{ "rd", F3(2, 0x28, 0), F3(~2, ~0x28, ~0)|RS1_G0|SIMM13(~0), "y,d", 0, v6 }, /* rd %y,r */ | |
| 1059 | +{ "rd", F3(2, 0x29, 0), F3(~2, ~0x29, ~0)|RS1_G0|SIMM13(~0), "p,d", 0, v6notv9 }, /* rd %psr,r */ | |
| 1060 | +{ "rd", F3(2, 0x2a, 0), F3(~2, ~0x2a, ~0)|RS1_G0|SIMM13(~0), "w,d", 0, v6notv9 }, /* rd %wim,r */ | |
| 1061 | +{ "rd", F3(2, 0x2b, 0), F3(~2, ~0x2b, ~0)|RS1_G0|SIMM13(~0), "t,d", 0, v6notv9 }, /* rd %tbr,r */ | |
| 1062 | + | |
| 1063 | +{ "rd", F3(2, 0x28, 0)|RS1(2), F3(~2, ~0x28, ~0)|RS1(~2)|SIMM13(~0), "E,d", 0, v9 }, /* rd %ccr,r */ | |
| 1064 | +{ "rd", F3(2, 0x28, 0)|RS1(3), F3(~2, ~0x28, ~0)|RS1(~3)|SIMM13(~0), "o,d", 0, v9 }, /* rd %asi,r */ | |
| 1065 | +{ "rd", F3(2, 0x28, 0)|RS1(4), F3(~2, ~0x28, ~0)|RS1(~4)|SIMM13(~0), "W,d", 0, v9 }, /* rd %tick,r */ | |
| 1066 | +{ "rd", F3(2, 0x28, 0)|RS1(5), F3(~2, ~0x28, ~0)|RS1(~5)|SIMM13(~0), "P,d", 0, v9 }, /* rd %pc,r */ | |
| 1067 | +{ "rd", F3(2, 0x28, 0)|RS1(6), F3(~2, ~0x28, ~0)|RS1(~6)|SIMM13(~0), "s,d", 0, v9 }, /* rd %fprs,r */ | |
| 1068 | + | |
| 1069 | +{ "rd", F3(2, 0x28, 0)|RS1(16), F3(~2, ~0x28, ~0)|RS1(~16)|SIMM13(~0), "/,d", 0, v9a }, /* rd %pcr,r */ | |
| 1070 | +{ "rd", F3(2, 0x28, 0)|RS1(17), F3(~2, ~0x28, ~0)|RS1(~17)|SIMM13(~0), "/,d", 0, v9a }, /* rd %pic,r */ | |
| 1071 | +{ "rd", F3(2, 0x28, 0)|RS1(18), F3(~2, ~0x28, ~0)|RS1(~18)|SIMM13(~0), "/,d", 0, v9a }, /* rd %dcr,r */ | |
| 1072 | +{ "rd", F3(2, 0x28, 0)|RS1(19), F3(~2, ~0x28, ~0)|RS1(~19)|SIMM13(~0), "/,d", 0, v9a }, /* rd %gsr,r */ | |
| 1073 | +{ "rd", F3(2, 0x28, 0)|RS1(22), F3(~2, ~0x28, ~0)|RS1(~22)|SIMM13(~0), "/,d", 0, v9a }, /* rd %softint,r */ | |
| 1074 | +{ "rd", F3(2, 0x28, 0)|RS1(23), F3(~2, ~0x28, ~0)|RS1(~23)|SIMM13(~0), "/,d", 0, v9a }, /* rd %tick_cmpr,r */ | |
| 1075 | +{ "rd", F3(2, 0x28, 0)|RS1(24), F3(~2, ~0x28, ~0)|RS1(~24)|SIMM13(~0), "/,d", 0, v9b }, /* rd %sys_tick,r */ | |
| 1076 | +{ "rd", F3(2, 0x28, 0)|RS1(25), F3(~2, ~0x28, ~0)|RS1(~25)|SIMM13(~0), "/,d", 0, v9b }, /* rd %sys_tick_cmpr,r */ | |
| 1077 | + | |
| 1078 | +{ "rdpr", F3(2, 0x2a, 0), F3(~2, ~0x2a, ~0)|SIMM13(~0), "?,d", 0, v9 }, /* rdpr %priv,r */ | |
| 1079 | +{ "wrpr", F3(2, 0x32, 0), F3(~2, ~0x32, ~0), "1,2,!", 0, v9 }, /* wrpr r1,r2,%priv */ | |
| 1080 | +{ "wrpr", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|SIMM13(~0), "1,!", 0, v9 }, /* wrpr r1,%priv */ | |
| 1081 | +{ "wrpr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1), "1,i,!", 0, v9 }, /* wrpr r1,i,%priv */ | |
| 1082 | +{ "wrpr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1), "i,1,!", F_ALIAS, v9 }, /* wrpr i,r1,%priv */ | |
| 1083 | +{ "wrpr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RS1(~0), "i,!", 0, v9 }, /* wrpr i,%priv */ | |
| 1084 | + | |
| 1085 | +/* ??? This group seems wrong. A three operand move? */ | |
| 1086 | +{ "mov", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|ASI(~0), "1,2,m", F_ALIAS, v8 }, /* wr r,r,%asrX */ | |
| 1087 | +{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1), "1,i,m", F_ALIAS, v8 }, /* wr r,i,%asrX */ | |
| 1088 | +{ "mov", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|RD_G0|ASI(~0), "1,2,y", F_ALIAS, v6 }, /* wr r,r,%y */ | |
| 1089 | +{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1)|RD_G0, "1,i,y", F_ALIAS, v6 }, /* wr r,i,%y */ | |
| 1090 | +{ "mov", F3(2, 0x31, 0), F3(~2, ~0x31, ~0)|RD_G0|ASI(~0), "1,2,p", F_ALIAS, v6notv9 }, /* wr r,r,%psr */ | |
| 1091 | +{ "mov", F3(2, 0x31, 1), F3(~2, ~0x31, ~1)|RD_G0, "1,i,p", F_ALIAS, v6notv9 }, /* wr r,i,%psr */ | |
| 1092 | +{ "mov", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|RD_G0|ASI(~0), "1,2,w", F_ALIAS, v6notv9 }, /* wr r,r,%wim */ | |
| 1093 | +{ "mov", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RD_G0, "1,i,w", F_ALIAS, v6notv9 }, /* wr r,i,%wim */ | |
| 1094 | +{ "mov", F3(2, 0x33, 0), F3(~2, ~0x33, ~0)|RD_G0|ASI(~0), "1,2,t", F_ALIAS, v6notv9 }, /* wr r,r,%tbr */ | |
| 1095 | +{ "mov", F3(2, 0x33, 1), F3(~2, ~0x33, ~1)|RD_G0, "1,i,t", F_ALIAS, v6notv9 }, /* wr r,i,%tbr */ | |
| 1096 | + | |
| 1097 | +{ "mov", F3(2, 0x28, 0), F3(~2, ~0x28, ~0)|SIMM13(~0), "M,d", F_ALIAS, v8 }, /* rd %asr1,r */ | |
| 1098 | +{ "mov", F3(2, 0x28, 0), F3(~2, ~0x28, ~0)|RS1_G0|SIMM13(~0), "y,d", F_ALIAS, v6 }, /* rd %y,r */ | |
| 1099 | +{ "mov", F3(2, 0x29, 0), F3(~2, ~0x29, ~0)|RS1_G0|SIMM13(~0), "p,d", F_ALIAS, v6notv9 }, /* rd %psr,r */ | |
| 1100 | +{ "mov", F3(2, 0x2a, 0), F3(~2, ~0x2a, ~0)|RS1_G0|SIMM13(~0), "w,d", F_ALIAS, v6notv9 }, /* rd %wim,r */ | |
| 1101 | +{ "mov", F3(2, 0x2b, 0), F3(~2, ~0x2b, ~0)|RS1_G0|SIMM13(~0), "t,d", F_ALIAS, v6notv9 }, /* rd %tbr,r */ | |
| 1102 | + | |
| 1103 | +{ "mov", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|ASI_RS2(~0), "1,m", F_ALIAS, v8 }, /* wr rs1,%g0,%asrX */ | |
| 1104 | +{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1), "i,m", F_ALIAS, v8 }, /* wr %g0,i,%asrX */ | |
| 1105 | +{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1)|SIMM13(~0), "1,m", F_ALIAS, v8 }, /* wr rs1,0,%asrX */ | |
| 1106 | +{ "mov", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|RD_G0|ASI_RS2(~0), "1,y", F_ALIAS, v6 }, /* wr rs1,%g0,%y */ | |
| 1107 | +{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1)|RD_G0, "i,y", F_ALIAS, v6 }, /* wr %g0,i,%y */ | |
| 1108 | +{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1)|RD_G0|SIMM13(~0), "1,y", F_ALIAS, v6 }, /* wr rs1,0,%y */ | |
| 1109 | +{ "mov", F3(2, 0x31, 0), F3(~2, ~0x31, ~0)|RD_G0|ASI_RS2(~0), "1,p", F_ALIAS, v6notv9 }, /* wr rs1,%g0,%psr */ | |
| 1110 | +{ "mov", F3(2, 0x31, 1), F3(~2, ~0x31, ~1)|RD_G0, "i,p", F_ALIAS, v6notv9 }, /* wr %g0,i,%psr */ | |
| 1111 | +{ "mov", F3(2, 0x31, 1), F3(~2, ~0x31, ~1)|RD_G0|SIMM13(~0), "1,p", F_ALIAS, v6notv9 }, /* wr rs1,0,%psr */ | |
| 1112 | +{ "mov", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|RD_G0|ASI_RS2(~0), "1,w", F_ALIAS, v6notv9 }, /* wr rs1,%g0,%wim */ | |
| 1113 | +{ "mov", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RD_G0, "i,w", F_ALIAS, v6notv9 }, /* wr %g0,i,%wim */ | |
| 1114 | +{ "mov", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RD_G0|SIMM13(~0), "1,w", F_ALIAS, v6notv9 }, /* wr rs1,0,%wim */ | |
| 1115 | +{ "mov", F3(2, 0x33, 0), F3(~2, ~0x33, ~0)|RD_G0|ASI_RS2(~0), "1,t", F_ALIAS, v6notv9 }, /* wr rs1,%g0,%tbr */ | |
| 1116 | +{ "mov", F3(2, 0x33, 1), F3(~2, ~0x33, ~1)|RD_G0, "i,t", F_ALIAS, v6notv9 }, /* wr %g0,i,%tbr */ | |
| 1117 | +{ "mov", F3(2, 0x33, 1), F3(~2, ~0x33, ~1)|RD_G0|SIMM13(~0), "1,t", F_ALIAS, v6notv9 }, /* wr rs1,0,%tbr */ | |
| 1118 | + | |
| 1119 | +{ "mov", F3(2, 0x02, 0), F3(~2, ~0x02, ~0)|RS1_G0|ASI(~0), "2,d", 0, v6 }, /* or %g0,rs2,d */ | |
| 1120 | +{ "mov", F3(2, 0x02, 1), F3(~2, ~0x02, ~1)|RS1_G0, "i,d", 0, v6 }, /* or %g0,i,d */ | |
| 1121 | +{ "mov", F3(2, 0x02, 0), F3(~2, ~0x02, ~0)|ASI_RS2(~0), "1,d", 0, v6 }, /* or rs1,%g0,d */ | |
| 1122 | +{ "mov", F3(2, 0x02, 1), F3(~2, ~0x02, ~1)|SIMM13(~0), "1,d", 0, v6 }, /* or rs1,0,d */ | |
| 1123 | + | |
| 1124 | +{ "or", F3(2, 0x02, 0), F3(~2, ~0x02, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1125 | +{ "or", F3(2, 0x02, 1), F3(~2, ~0x02, ~1), "1,i,d", 0, v6 }, | |
| 1126 | +{ "or", F3(2, 0x02, 1), F3(~2, ~0x02, ~1), "i,1,d", 0, v6 }, | |
| 1127 | + | |
| 1128 | +{ "bset", F3(2, 0x02, 0), F3(~2, ~0x02, ~0)|ASI(~0), "2,r", F_ALIAS, v6 }, /* or rd,rs2,rd */ | |
| 1129 | +{ "bset", F3(2, 0x02, 1), F3(~2, ~0x02, ~1), "i,r", F_ALIAS, v6 }, /* or rd,i,rd */ | |
| 1130 | + | |
| 1131 | +/* This is not a commutative instruction. */ | |
| 1132 | +{ "andn", F3(2, 0x05, 0), F3(~2, ~0x05, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1133 | +{ "andn", F3(2, 0x05, 1), F3(~2, ~0x05, ~1), "1,i,d", 0, v6 }, | |
| 1134 | + | |
| 1135 | +/* This is not a commutative instruction. */ | |
| 1136 | +{ "andncc", F3(2, 0x15, 0), F3(~2, ~0x15, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1137 | +{ "andncc", F3(2, 0x15, 1), F3(~2, ~0x15, ~1), "1,i,d", 0, v6 }, | |
| 1138 | + | |
| 1139 | +{ "bclr", F3(2, 0x05, 0), F3(~2, ~0x05, ~0)|ASI(~0), "2,r", F_ALIAS, v6 }, /* andn rd,rs2,rd */ | |
| 1140 | +{ "bclr", F3(2, 0x05, 1), F3(~2, ~0x05, ~1), "i,r", F_ALIAS, v6 }, /* andn rd,i,rd */ | |
| 1141 | + | |
| 1142 | +{ "cmp", F3(2, 0x14, 0), F3(~2, ~0x14, ~0)|RD_G0|ASI(~0), "1,2", 0, v6 }, /* subcc rs1,rs2,%g0 */ | |
| 1143 | +{ "cmp", F3(2, 0x14, 1), F3(~2, ~0x14, ~1)|RD_G0, "1,i", 0, v6 }, /* subcc rs1,i,%g0 */ | |
| 1144 | + | |
| 1145 | +{ "sub", F3(2, 0x04, 0), F3(~2, ~0x04, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1146 | +{ "sub", F3(2, 0x04, 1), F3(~2, ~0x04, ~1), "1,i,d", 0, v6 }, | |
| 1147 | + | |
| 1148 | +{ "subcc", F3(2, 0x14, 0), F3(~2, ~0x14, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1149 | +{ "subcc", F3(2, 0x14, 1), F3(~2, ~0x14, ~1), "1,i,d", 0, v6 }, | |
| 1150 | + | |
| 1151 | +{ "subx", F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0), "1,2,d", 0, v6notv9 }, | |
| 1152 | +{ "subx", F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1), "1,i,d", 0, v6notv9 }, | |
| 1153 | +{ "subc", F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0), "1,2,d", 0, v9 }, | |
| 1154 | +{ "subc", F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1), "1,i,d", 0, v9 }, | |
| 1155 | + | |
| 1156 | +{ "subxcc", F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0), "1,2,d", 0, v6notv9 }, | |
| 1157 | +{ "subxcc", F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1), "1,i,d", 0, v6notv9 }, | |
| 1158 | +{ "subccc", F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0), "1,2,d", 0, v9 }, | |
| 1159 | +{ "subccc", F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1), "1,i,d", 0, v9 }, | |
| 1160 | + | |
| 1161 | +{ "and", F3(2, 0x01, 0), F3(~2, ~0x01, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1162 | +{ "and", F3(2, 0x01, 1), F3(~2, ~0x01, ~1), "1,i,d", 0, v6 }, | |
| 1163 | +{ "and", F3(2, 0x01, 1), F3(~2, ~0x01, ~1), "i,1,d", 0, v6 }, | |
| 1164 | + | |
| 1165 | +{ "andcc", F3(2, 0x11, 0), F3(~2, ~0x11, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1166 | +{ "andcc", F3(2, 0x11, 1), F3(~2, ~0x11, ~1), "1,i,d", 0, v6 }, | |
| 1167 | +{ "andcc", F3(2, 0x11, 1), F3(~2, ~0x11, ~1), "i,1,d", 0, v6 }, | |
| 1168 | + | |
| 1169 | +{ "dec", F3(2, 0x04, 1)|SIMM13(0x1), F3(~2, ~0x04, ~1)|SIMM13(~0x0001), "r", F_ALIAS, v6 }, /* sub rd,1,rd */ | |
| 1170 | +{ "dec", F3(2, 0x04, 1), F3(~2, ~0x04, ~1), "i,r", F_ALIAS, v8 }, /* sub rd,imm,rd */ | |
| 1171 | +{ "deccc", F3(2, 0x14, 1)|SIMM13(0x1), F3(~2, ~0x14, ~1)|SIMM13(~0x0001), "r", F_ALIAS, v6 }, /* subcc rd,1,rd */ | |
| 1172 | +{ "deccc", F3(2, 0x14, 1), F3(~2, ~0x14, ~1), "i,r", F_ALIAS, v8 }, /* subcc rd,imm,rd */ | |
| 1173 | +{ "inc", F3(2, 0x00, 1)|SIMM13(0x1), F3(~2, ~0x00, ~1)|SIMM13(~0x0001), "r", F_ALIAS, v6 }, /* add rd,1,rd */ | |
| 1174 | +{ "inc", F3(2, 0x00, 1), F3(~2, ~0x00, ~1), "i,r", F_ALIAS, v8 }, /* add rd,imm,rd */ | |
| 1175 | +{ "inccc", F3(2, 0x10, 1)|SIMM13(0x1), F3(~2, ~0x10, ~1)|SIMM13(~0x0001), "r", F_ALIAS, v6 }, /* addcc rd,1,rd */ | |
| 1176 | +{ "inccc", F3(2, 0x10, 1), F3(~2, ~0x10, ~1), "i,r", F_ALIAS, v8 }, /* addcc rd,imm,rd */ | |
| 1177 | + | |
| 1178 | +{ "btst", F3(2, 0x11, 0), F3(~2, ~0x11, ~0)|RD_G0|ASI(~0), "1,2", F_ALIAS, v6 }, /* andcc rs1,rs2,%g0 */ | |
| 1179 | +{ "btst", F3(2, 0x11, 1), F3(~2, ~0x11, ~1)|RD_G0, "i,1", F_ALIAS, v6 }, /* andcc rs1,i,%g0 */ | |
| 1180 | + | |
| 1181 | +{ "neg", F3(2, 0x04, 0), F3(~2, ~0x04, ~0)|RS1_G0|ASI(~0), "2,d", F_ALIAS, v6 }, /* sub %g0,rs2,rd */ | |
| 1182 | +{ "neg", F3(2, 0x04, 0), F3(~2, ~0x04, ~0)|RS1_G0|ASI(~0), "O", F_ALIAS, v6 }, /* sub %g0,rd,rd */ | |
| 1183 | + | |
| 1184 | +{ "add", F3(2, 0x00, 0), F3(~2, ~0x00, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1185 | +{ "add", F3(2, 0x00, 1), F3(~2, ~0x00, ~1), "1,i,d", 0, v6 }, | |
| 1186 | +{ "add", F3(2, 0x00, 1), F3(~2, ~0x00, ~1), "i,1,d", 0, v6 }, | |
| 1187 | +{ "addcc", F3(2, 0x10, 0), F3(~2, ~0x10, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1188 | +{ "addcc", F3(2, 0x10, 1), F3(~2, ~0x10, ~1), "1,i,d", 0, v6 }, | |
| 1189 | +{ "addcc", F3(2, 0x10, 1), F3(~2, ~0x10, ~1), "i,1,d", 0, v6 }, | |
| 1190 | + | |
| 1191 | +{ "addx", F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0), "1,2,d", 0, v6notv9 }, | |
| 1192 | +{ "addx", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "1,i,d", 0, v6notv9 }, | |
| 1193 | +{ "addx", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "i,1,d", 0, v6notv9 }, | |
| 1194 | +{ "addc", F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0), "1,2,d", 0, v9 }, | |
| 1195 | +{ "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "1,i,d", 0, v9 }, | |
| 1196 | +{ "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "i,1,d", 0, v9 }, | |
| 1197 | + | |
| 1198 | +{ "addxcc", F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0), "1,2,d", 0, v6notv9 }, | |
| 1199 | +{ "addxcc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "1,i,d", 0, v6notv9 }, | |
| 1200 | +{ "addxcc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "i,1,d", 0, v6notv9 }, | |
| 1201 | +{ "addccc", F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0), "1,2,d", 0, v9 }, | |
| 1202 | +{ "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "1,i,d", 0, v9 }, | |
| 1203 | +{ "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "i,1,d", 0, v9 }, | |
| 1204 | + | |
| 1205 | +{ "smul", F3(2, 0x0b, 0), F3(~2, ~0x0b, ~0)|ASI(~0), "1,2,d", 0, v8 }, | |
| 1206 | +{ "smul", F3(2, 0x0b, 1), F3(~2, ~0x0b, ~1), "1,i,d", 0, v8 }, | |
| 1207 | +{ "smul", F3(2, 0x0b, 1), F3(~2, ~0x0b, ~1), "i,1,d", 0, v8 }, | |
| 1208 | +{ "smulcc", F3(2, 0x1b, 0), F3(~2, ~0x1b, ~0)|ASI(~0), "1,2,d", 0, v8 }, | |
| 1209 | +{ "smulcc", F3(2, 0x1b, 1), F3(~2, ~0x1b, ~1), "1,i,d", 0, v8 }, | |
| 1210 | +{ "smulcc", F3(2, 0x1b, 1), F3(~2, ~0x1b, ~1), "i,1,d", 0, v8 }, | |
| 1211 | +{ "umul", F3(2, 0x0a, 0), F3(~2, ~0x0a, ~0)|ASI(~0), "1,2,d", 0, v8 }, | |
| 1212 | +{ "umul", F3(2, 0x0a, 1), F3(~2, ~0x0a, ~1), "1,i,d", 0, v8 }, | |
| 1213 | +{ "umul", F3(2, 0x0a, 1), F3(~2, ~0x0a, ~1), "i,1,d", 0, v8 }, | |
| 1214 | +{ "umulcc", F3(2, 0x1a, 0), F3(~2, ~0x1a, ~0)|ASI(~0), "1,2,d", 0, v8 }, | |
| 1215 | +{ "umulcc", F3(2, 0x1a, 1), F3(~2, ~0x1a, ~1), "1,i,d", 0, v8 }, | |
| 1216 | +{ "umulcc", F3(2, 0x1a, 1), F3(~2, ~0x1a, ~1), "i,1,d", 0, v8 }, | |
| 1217 | +{ "sdiv", F3(2, 0x0f, 0), F3(~2, ~0x0f, ~0)|ASI(~0), "1,2,d", 0, v8 }, | |
| 1218 | +{ "sdiv", F3(2, 0x0f, 1), F3(~2, ~0x0f, ~1), "1,i,d", 0, v8 }, | |
| 1219 | +{ "sdiv", F3(2, 0x0f, 1), F3(~2, ~0x0f, ~1), "i,1,d", 0, v8 }, | |
| 1220 | +{ "sdivcc", F3(2, 0x1f, 0), F3(~2, ~0x1f, ~0)|ASI(~0), "1,2,d", 0, v8 }, | |
| 1221 | +{ "sdivcc", F3(2, 0x1f, 1), F3(~2, ~0x1f, ~1), "1,i,d", 0, v8 }, | |
| 1222 | +{ "sdivcc", F3(2, 0x1f, 1), F3(~2, ~0x1f, ~1), "i,1,d", 0, v8 }, | |
| 1223 | +{ "udiv", F3(2, 0x0e, 0), F3(~2, ~0x0e, ~0)|ASI(~0), "1,2,d", 0, v8 }, | |
| 1224 | +{ "udiv", F3(2, 0x0e, 1), F3(~2, ~0x0e, ~1), "1,i,d", 0, v8 }, | |
| 1225 | +{ "udiv", F3(2, 0x0e, 1), F3(~2, ~0x0e, ~1), "i,1,d", 0, v8 }, | |
| 1226 | +{ "udivcc", F3(2, 0x1e, 0), F3(~2, ~0x1e, ~0)|ASI(~0), "1,2,d", 0, v8 }, | |
| 1227 | +{ "udivcc", F3(2, 0x1e, 1), F3(~2, ~0x1e, ~1), "1,i,d", 0, v8 }, | |
| 1228 | +{ "udivcc", F3(2, 0x1e, 1), F3(~2, ~0x1e, ~1), "i,1,d", 0, v8 }, | |
| 1229 | + | |
| 1230 | +{ "mulx", F3(2, 0x09, 0), F3(~2, ~0x09, ~0)|ASI(~0), "1,2,d", 0, v9 }, | |
| 1231 | +{ "mulx", F3(2, 0x09, 1), F3(~2, ~0x09, ~1), "1,i,d", 0, v9 }, | |
| 1232 | +{ "sdivx", F3(2, 0x2d, 0), F3(~2, ~0x2d, ~0)|ASI(~0), "1,2,d", 0, v9 }, | |
| 1233 | +{ "sdivx", F3(2, 0x2d, 1), F3(~2, ~0x2d, ~1), "1,i,d", 0, v9 }, | |
| 1234 | +{ "udivx", F3(2, 0x0d, 0), F3(~2, ~0x0d, ~0)|ASI(~0), "1,2,d", 0, v9 }, | |
| 1235 | +{ "udivx", F3(2, 0x0d, 1), F3(~2, ~0x0d, ~1), "1,i,d", 0, v9 }, | |
| 1236 | + | |
| 1237 | +{ "call", F1(0x1), F1(~0x1), "L", F_JSR|F_DELAYED, v6 }, | |
| 1238 | +{ "call", F1(0x1), F1(~0x1), "L,#", F_JSR|F_DELAYED, v6 }, | |
| 1239 | + | |
| 1240 | +{ "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf)|ASI(~0), "1+2", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+rs2,%o7 */ | |
| 1241 | +{ "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf)|ASI(~0), "1+2,#", F_JSR|F_DELAYED, v6 }, | |
| 1242 | +{ "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf)|ASI_RS2(~0), "1", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+%g0,%o7 */ | |
| 1243 | +{ "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf)|ASI_RS2(~0), "1,#", F_JSR|F_DELAYED, v6 }, | |
| 1244 | +{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf), "1+i", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+i,%o7 */ | |
| 1245 | +{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf), "1+i,#", F_JSR|F_DELAYED, v6 }, | |
| 1246 | +{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf), "i+1", F_JSR|F_DELAYED, v6 }, /* jmpl i+rs1,%o7 */ | |
| 1247 | +{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf), "i+1,#", F_JSR|F_DELAYED, v6 }, | |
| 1248 | +{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf)|RS1_G0, "i", F_JSR|F_DELAYED, v6 }, /* jmpl %g0+i,%o7 */ | |
| 1249 | +{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf)|RS1_G0, "i,#", F_JSR|F_DELAYED, v6 }, | |
| 1250 | +{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf)|SIMM13(~0), "1", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+0,%o7 */ | |
| 1251 | +{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf)|SIMM13(~0), "1,#", F_JSR|F_DELAYED, v6 }, | |
| 1252 | + | |
| 1253 | + | |
| 1254 | +/* Conditional instructions. | |
| 1255 | + | |
| 1256 | + Because this part of the table was such a mess earlier, I have | |
| 1257 | + macrofied it so that all the branches and traps are generated from | |
| 1258 | + a single-line description of each condition value. John Gilmore. */ | |
| 1259 | + | |
| 1260 | +/* Define branches -- one annulled, one without, etc. */ | |
| 1261 | +#define br(opcode, mask, lose, flags) \ | |
| 1262 | + { opcode, (mask)|ANNUL, (lose), ",a l", (flags), v6 }, \ | |
| 1263 | + { opcode, (mask) , (lose)|ANNUL, "l", (flags), v6 } | |
| 1264 | + | |
| 1265 | +#define brx(opcode, mask, lose, flags) /* v9 */ \ | |
| 1266 | + { opcode, (mask)|(2<<20)|BPRED, ANNUL|(lose), "Z,G", (flags), v9 }, \ | |
| 1267 | + { opcode, (mask)|(2<<20)|BPRED, ANNUL|(lose), ",T Z,G", (flags), v9 }, \ | |
| 1268 | + { opcode, (mask)|(2<<20)|BPRED|ANNUL, (lose), ",a Z,G", (flags), v9 }, \ | |
| 1269 | + { opcode, (mask)|(2<<20)|BPRED|ANNUL, (lose), ",a,T Z,G", (flags), v9 }, \ | |
| 1270 | + { opcode, (mask)|(2<<20), ANNUL|BPRED|(lose), ",N Z,G", (flags), v9 }, \ | |
| 1271 | + { opcode, (mask)|(2<<20)|ANNUL, BPRED|(lose), ",a,N Z,G", (flags), v9 }, \ | |
| 1272 | + { opcode, (mask)|BPRED, ANNUL|(lose)|(2<<20), "z,G", (flags), v9 }, \ | |
| 1273 | + { opcode, (mask)|BPRED, ANNUL|(lose)|(2<<20), ",T z,G", (flags), v9 }, \ | |
| 1274 | + { opcode, (mask)|BPRED|ANNUL, (lose)|(2<<20), ",a z,G", (flags), v9 }, \ | |
| 1275 | + { opcode, (mask)|BPRED|ANNUL, (lose)|(2<<20), ",a,T z,G", (flags), v9 }, \ | |
| 1276 | + { opcode, (mask), ANNUL|BPRED|(lose)|(2<<20), ",N z,G", (flags), v9 }, \ | |
| 1277 | + { opcode, (mask)|ANNUL, BPRED|(lose)|(2<<20), ",a,N z,G", (flags), v9 } | |
| 1278 | + | |
| 1279 | +/* Define four traps: reg+reg, reg + immediate, immediate alone, reg alone. */ | |
| 1280 | +#define tr(opcode, mask, lose, flags) \ | |
| 1281 | + { opcode, (mask)|(2<<11)|IMMED, (lose)|RS1_G0, "Z,i", (flags), v9 }, /* %g0 + imm */ \ | |
| 1282 | + { opcode, (mask)|(2<<11)|IMMED, (lose), "Z,1+i", (flags), v9 }, /* rs1 + imm */ \ | |
| 1283 | + { opcode, (mask)|(2<<11), IMMED|(lose), "Z,1+2", (flags), v9 }, /* rs1 + rs2 */ \ | |
| 1284 | + { opcode, (mask)|(2<<11), IMMED|(lose)|RS2_G0, "Z,1", (flags), v9 }, /* rs1 + %g0 */ \ | |
| 1285 | + { opcode, (mask)|IMMED, (lose)|RS1_G0, "z,i", (flags)|F_ALIAS, v9 }, /* %g0 + imm */ \ | |
| 1286 | + { opcode, (mask)|IMMED, (lose), "z,1+i", (flags)|F_ALIAS, v9 }, /* rs1 + imm */ \ | |
| 1287 | + { opcode, (mask), IMMED|(lose), "z,1+2", (flags)|F_ALIAS, v9 }, /* rs1 + rs2 */ \ | |
| 1288 | + { opcode, (mask), IMMED|(lose)|RS2_G0, "z,1", (flags)|F_ALIAS, v9 }, /* rs1 + %g0 */ \ | |
| 1289 | + { opcode, (mask)|IMMED, (lose)|RS1_G0, "i", (flags), v6 }, /* %g0 + imm */ \ | |
| 1290 | + { opcode, (mask)|IMMED, (lose), "1+i", (flags), v6 }, /* rs1 + imm */ \ | |
| 1291 | + { opcode, (mask), IMMED|(lose), "1+2", (flags), v6 }, /* rs1 + rs2 */ \ | |
| 1292 | + { opcode, (mask), IMMED|(lose)|RS2_G0, "1", (flags), v6 } /* rs1 + %g0 */ | |
| 1293 | + | |
| 1294 | +/* v9: We must put `brx' before `br', to ensure that we never match something | |
| 1295 | + v9: against an expression unless it is an expression. Otherwise, we end | |
| 1296 | + v9: up with undefined symbol tables entries, because they get added, but | |
| 1297 | + v9: are not deleted if the pattern fails to match. */ | |
| 1298 | + | |
| 1299 | +/* Define both branches and traps based on condition mask */ | |
| 1300 | +#define cond(bop, top, mask, flags) \ | |
| 1301 | + brx(bop, F2(0, 1)|(mask), F2(~0, ~1)|((~mask)&COND(~0)), F_DELAYED|(flags)), /* v9 */ \ | |
| 1302 | + br(bop, F2(0, 2)|(mask), F2(~0, ~2)|((~mask)&COND(~0)), F_DELAYED|(flags)), \ | |
| 1303 | + tr(top, F3(2, 0x3a, 0)|(mask), F3(~2, ~0x3a, 0)|((~mask)&COND(~0)), ((flags) & ~(F_UNBR|F_CONDBR))) | |
| 1304 | + | |
| 1305 | +/* Define all the conditions, all the branches, all the traps. */ | |
| 1306 | + | |
| 1307 | +/* Standard branch, trap mnemonics */ | |
| 1308 | +cond ("b", "ta", CONDA, F_UNBR), | |
| 1309 | +/* Alternative form (just for assembly, not for disassembly) */ | |
| 1310 | +cond ("ba", "t", CONDA, F_UNBR|F_ALIAS), | |
| 1311 | + | |
| 1312 | +cond ("bcc", "tcc", CONDCC, F_CONDBR), | |
| 1313 | +cond ("bcs", "tcs", CONDCS, F_CONDBR), | |
| 1314 | +cond ("be", "te", CONDE, F_CONDBR), | |
| 1315 | +cond ("beq", "teq", CONDE, F_CONDBR|F_ALIAS), | |
| 1316 | +cond ("bg", "tg", CONDG, F_CONDBR), | |
| 1317 | +cond ("bgt", "tgt", CONDG, F_CONDBR|F_ALIAS), | |
| 1318 | +cond ("bge", "tge", CONDGE, F_CONDBR), | |
| 1319 | +cond ("bgeu", "tgeu", CONDGEU, F_CONDBR|F_ALIAS), /* for cc */ | |
| 1320 | +cond ("bgu", "tgu", CONDGU, F_CONDBR), | |
| 1321 | +cond ("bl", "tl", CONDL, F_CONDBR), | |
| 1322 | +cond ("blt", "tlt", CONDL, F_CONDBR|F_ALIAS), | |
| 1323 | +cond ("ble", "tle", CONDLE, F_CONDBR), | |
| 1324 | +cond ("bleu", "tleu", CONDLEU, F_CONDBR), | |
| 1325 | +cond ("blu", "tlu", CONDLU, F_CONDBR|F_ALIAS), /* for cs */ | |
| 1326 | +cond ("bn", "tn", CONDN, F_CONDBR), | |
| 1327 | +cond ("bne", "tne", CONDNE, F_CONDBR), | |
| 1328 | +cond ("bneg", "tneg", CONDNEG, F_CONDBR), | |
| 1329 | +cond ("bnz", "tnz", CONDNZ, F_CONDBR|F_ALIAS), /* for ne */ | |
| 1330 | +cond ("bpos", "tpos", CONDPOS, F_CONDBR), | |
| 1331 | +cond ("bvc", "tvc", CONDVC, F_CONDBR), | |
| 1332 | +cond ("bvs", "tvs", CONDVS, F_CONDBR), | |
| 1333 | +cond ("bz", "tz", CONDZ, F_CONDBR|F_ALIAS), /* for e */ | |
| 1334 | + | |
| 1335 | +#undef cond | |
| 1336 | +#undef br | |
| 1337 | +#undef brr /* v9 */ | |
| 1338 | +#undef tr | |
| 1339 | + | |
| 1340 | +#define brr(opcode, mask, lose, flags) /* v9 */ \ | |
| 1341 | + { opcode, (mask)|BPRED, ANNUL|(lose), "1,k", F_DELAYED|(flags), v9 }, \ | |
| 1342 | + { opcode, (mask)|BPRED, ANNUL|(lose), ",T 1,k", F_DELAYED|(flags), v9 }, \ | |
| 1343 | + { opcode, (mask)|BPRED|ANNUL, (lose), ",a 1,k", F_DELAYED|(flags), v9 }, \ | |
| 1344 | + { opcode, (mask)|BPRED|ANNUL, (lose), ",a,T 1,k", F_DELAYED|(flags), v9 }, \ | |
| 1345 | + { opcode, (mask), ANNUL|BPRED|(lose), ",N 1,k", F_DELAYED|(flags), v9 }, \ | |
| 1346 | + { opcode, (mask)|ANNUL, BPRED|(lose), ",a,N 1,k", F_DELAYED|(flags), v9 } | |
| 1347 | + | |
| 1348 | +#define condr(bop, mask, flags) /* v9 */ \ | |
| 1349 | + brr(bop, F2(0, 3)|COND(mask), F2(~0, ~3)|COND(~(mask)), (flags)) /* v9 */ | |
| 1350 | + | |
| 1351 | +/* v9 */ condr("brnz", 0x5, F_CONDBR), | |
| 1352 | +/* v9 */ condr("brz", 0x1, F_CONDBR), | |
| 1353 | +/* v9 */ condr("brgez", 0x7, F_CONDBR), | |
| 1354 | +/* v9 */ condr("brlz", 0x3, F_CONDBR), | |
| 1355 | +/* v9 */ condr("brlez", 0x2, F_CONDBR), | |
| 1356 | +/* v9 */ condr("brgz", 0x6, F_CONDBR), | |
| 1357 | + | |
| 1358 | +#undef condr /* v9 */ | |
| 1359 | +#undef brr /* v9 */ | |
| 1360 | + | |
| 1361 | +#define movr(opcode, mask, flags) /* v9 */ \ | |
| 1362 | + { opcode, F3(2, 0x2f, 0)|RCOND(mask), F3(~2, ~0x2f, ~0)|RCOND(~(mask)), "1,2,d", (flags), v9 }, \ | |
| 1363 | + { opcode, F3(2, 0x2f, 1)|RCOND(mask), F3(~2, ~0x2f, ~1)|RCOND(~(mask)), "1,j,d", (flags), v9 } | |
| 1364 | + | |
| 1365 | +#define fmrrs(opcode, mask, lose, flags) /* v9 */ \ | |
| 1366 | + { opcode, (mask), (lose), "1,f,g", (flags) | F_FLOAT, v9 } | |
| 1367 | +#define fmrrd(opcode, mask, lose, flags) /* v9 */ \ | |
| 1368 | + { opcode, (mask), (lose), "1,B,H", (flags) | F_FLOAT, v9 } | |
| 1369 | +#define fmrrq(opcode, mask, lose, flags) /* v9 */ \ | |
| 1370 | + { opcode, (mask), (lose), "1,R,J", (flags) | F_FLOAT, v9 } | |
| 1371 | + | |
| 1372 | +#define fmovrs(mop, mask, flags) /* v9 */ \ | |
| 1373 | + fmrrs(mop, F3(2, 0x35, 0)|OPF_LOW5(5)|RCOND(mask), F3(~2, ~0x35, 0)|OPF_LOW5(~5)|RCOND(~(mask)), (flags)) /* v9 */ | |
| 1374 | +#define fmovrd(mop, mask, flags) /* v9 */ \ | |
| 1375 | + fmrrd(mop, F3(2, 0x35, 0)|OPF_LOW5(6)|RCOND(mask), F3(~2, ~0x35, 0)|OPF_LOW5(~6)|RCOND(~(mask)), (flags)) /* v9 */ | |
| 1376 | +#define fmovrq(mop, mask, flags) /* v9 */ \ | |
| 1377 | + fmrrq(mop, F3(2, 0x35, 0)|OPF_LOW5(7)|RCOND(mask), F3(~2, ~0x35, 0)|OPF_LOW5(~7)|RCOND(~(mask)), (flags)) /* v9 */ | |
| 1378 | + | |
| 1379 | +/* v9 */ movr("movrne", 0x5, 0), | |
| 1380 | +/* v9 */ movr("movre", 0x1, 0), | |
| 1381 | +/* v9 */ movr("movrgez", 0x7, 0), | |
| 1382 | +/* v9 */ movr("movrlz", 0x3, 0), | |
| 1383 | +/* v9 */ movr("movrlez", 0x2, 0), | |
| 1384 | +/* v9 */ movr("movrgz", 0x6, 0), | |
| 1385 | +/* v9 */ movr("movrnz", 0x5, F_ALIAS), | |
| 1386 | +/* v9 */ movr("movrz", 0x1, F_ALIAS), | |
| 1387 | + | |
| 1388 | +/* v9 */ fmovrs("fmovrsne", 0x5, 0), | |
| 1389 | +/* v9 */ fmovrs("fmovrse", 0x1, 0), | |
| 1390 | +/* v9 */ fmovrs("fmovrsgez", 0x7, 0), | |
| 1391 | +/* v9 */ fmovrs("fmovrslz", 0x3, 0), | |
| 1392 | +/* v9 */ fmovrs("fmovrslez", 0x2, 0), | |
| 1393 | +/* v9 */ fmovrs("fmovrsgz", 0x6, 0), | |
| 1394 | +/* v9 */ fmovrs("fmovrsnz", 0x5, F_ALIAS), | |
| 1395 | +/* v9 */ fmovrs("fmovrsz", 0x1, F_ALIAS), | |
| 1396 | + | |
| 1397 | +/* v9 */ fmovrd("fmovrdne", 0x5, 0), | |
| 1398 | +/* v9 */ fmovrd("fmovrde", 0x1, 0), | |
| 1399 | +/* v9 */ fmovrd("fmovrdgez", 0x7, 0), | |
| 1400 | +/* v9 */ fmovrd("fmovrdlz", 0x3, 0), | |
| 1401 | +/* v9 */ fmovrd("fmovrdlez", 0x2, 0), | |
| 1402 | +/* v9 */ fmovrd("fmovrdgz", 0x6, 0), | |
| 1403 | +/* v9 */ fmovrd("fmovrdnz", 0x5, F_ALIAS), | |
| 1404 | +/* v9 */ fmovrd("fmovrdz", 0x1, F_ALIAS), | |
| 1405 | + | |
| 1406 | +/* v9 */ fmovrq("fmovrqne", 0x5, 0), | |
| 1407 | +/* v9 */ fmovrq("fmovrqe", 0x1, 0), | |
| 1408 | +/* v9 */ fmovrq("fmovrqgez", 0x7, 0), | |
| 1409 | +/* v9 */ fmovrq("fmovrqlz", 0x3, 0), | |
| 1410 | +/* v9 */ fmovrq("fmovrqlez", 0x2, 0), | |
| 1411 | +/* v9 */ fmovrq("fmovrqgz", 0x6, 0), | |
| 1412 | +/* v9 */ fmovrq("fmovrqnz", 0x5, F_ALIAS), | |
| 1413 | +/* v9 */ fmovrq("fmovrqz", 0x1, F_ALIAS), | |
| 1414 | + | |
| 1415 | +#undef movr /* v9 */ | |
| 1416 | +#undef fmovr /* v9 */ | |
| 1417 | +#undef fmrr /* v9 */ | |
| 1418 | + | |
| 1419 | +#define movicc(opcode, cond, flags) /* v9 */ \ | |
| 1420 | + { opcode, F3(2, 0x2c, 0)|MCOND(cond,1)|ICC, F3(~2, ~0x2c, ~0)|MCOND(~cond,~1)|XCC|(1<<11), "z,2,d", flags, v9 }, \ | |
| 1421 | + { opcode, F3(2, 0x2c, 1)|MCOND(cond,1)|ICC, F3(~2, ~0x2c, ~1)|MCOND(~cond,~1)|XCC|(1<<11), "z,I,d", flags, v9 }, \ | |
| 1422 | + { opcode, F3(2, 0x2c, 0)|MCOND(cond,1)|XCC, F3(~2, ~0x2c, ~0)|MCOND(~cond,~1)|(1<<11), "Z,2,d", flags, v9 }, \ | |
| 1423 | + { opcode, F3(2, 0x2c, 1)|MCOND(cond,1)|XCC, F3(~2, ~0x2c, ~1)|MCOND(~cond,~1)|(1<<11), "Z,I,d", flags, v9 } | |
| 1424 | + | |
| 1425 | +#define movfcc(opcode, fcond, flags) /* v9 */ \ | |
| 1426 | + { opcode, F3(2, 0x2c, 0)|FCC(0)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~0)|F3(~2, ~0x2c, ~0), "6,2,d", flags, v9 }, \ | |
| 1427 | + { opcode, F3(2, 0x2c, 1)|FCC(0)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~0)|F3(~2, ~0x2c, ~1), "6,I,d", flags, v9 }, \ | |
| 1428 | + { opcode, F3(2, 0x2c, 0)|FCC(1)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~1)|F3(~2, ~0x2c, ~0), "7,2,d", flags, v9 }, \ | |
| 1429 | + { opcode, F3(2, 0x2c, 1)|FCC(1)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~1)|F3(~2, ~0x2c, ~1), "7,I,d", flags, v9 }, \ | |
| 1430 | + { opcode, F3(2, 0x2c, 0)|FCC(2)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~2)|F3(~2, ~0x2c, ~0), "8,2,d", flags, v9 }, \ | |
| 1431 | + { opcode, F3(2, 0x2c, 1)|FCC(2)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~2)|F3(~2, ~0x2c, ~1), "8,I,d", flags, v9 }, \ | |
| 1432 | + { opcode, F3(2, 0x2c, 0)|FCC(3)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~3)|F3(~2, ~0x2c, ~0), "9,2,d", flags, v9 }, \ | |
| 1433 | + { opcode, F3(2, 0x2c, 1)|FCC(3)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~3)|F3(~2, ~0x2c, ~1), "9,I,d", flags, v9 } | |
| 1434 | + | |
| 1435 | +#define movcc(opcode, cond, fcond, flags) /* v9 */ \ | |
| 1436 | + movfcc (opcode, fcond, flags), /* v9 */ \ | |
| 1437 | + movicc (opcode, cond, flags) /* v9 */ | |
| 1438 | + | |
| 1439 | +/* v9 */ movcc ("mova", CONDA, FCONDA, 0), | |
| 1440 | +/* v9 */ movicc ("movcc", CONDCC, 0), | |
| 1441 | +/* v9 */ movicc ("movgeu", CONDGEU, F_ALIAS), | |
| 1442 | +/* v9 */ movicc ("movcs", CONDCS, 0), | |
| 1443 | +/* v9 */ movicc ("movlu", CONDLU, F_ALIAS), | |
| 1444 | +/* v9 */ movcc ("move", CONDE, FCONDE, 0), | |
| 1445 | +/* v9 */ movcc ("movg", CONDG, FCONDG, 0), | |
| 1446 | +/* v9 */ movcc ("movge", CONDGE, FCONDGE, 0), | |
| 1447 | +/* v9 */ movicc ("movgu", CONDGU, 0), | |
| 1448 | +/* v9 */ movcc ("movl", CONDL, FCONDL, 0), | |
| 1449 | +/* v9 */ movcc ("movle", CONDLE, FCONDLE, 0), | |
| 1450 | +/* v9 */ movicc ("movleu", CONDLEU, 0), | |
| 1451 | +/* v9 */ movfcc ("movlg", FCONDLG, 0), | |
| 1452 | +/* v9 */ movcc ("movn", CONDN, FCONDN, 0), | |
| 1453 | +/* v9 */ movcc ("movne", CONDNE, FCONDNE, 0), | |
| 1454 | +/* v9 */ movicc ("movneg", CONDNEG, 0), | |
| 1455 | +/* v9 */ movcc ("movnz", CONDNZ, FCONDNZ, F_ALIAS), | |
| 1456 | +/* v9 */ movfcc ("movo", FCONDO, 0), | |
| 1457 | +/* v9 */ movicc ("movpos", CONDPOS, 0), | |
| 1458 | +/* v9 */ movfcc ("movu", FCONDU, 0), | |
| 1459 | +/* v9 */ movfcc ("movue", FCONDUE, 0), | |
| 1460 | +/* v9 */ movfcc ("movug", FCONDUG, 0), | |
| 1461 | +/* v9 */ movfcc ("movuge", FCONDUGE, 0), | |
| 1462 | +/* v9 */ movfcc ("movul", FCONDUL, 0), | |
| 1463 | +/* v9 */ movfcc ("movule", FCONDULE, 0), | |
| 1464 | +/* v9 */ movicc ("movvc", CONDVC, 0), | |
| 1465 | +/* v9 */ movicc ("movvs", CONDVS, 0), | |
| 1466 | +/* v9 */ movcc ("movz", CONDZ, FCONDZ, F_ALIAS), | |
| 1467 | + | |
| 1468 | +#undef movicc /* v9 */ | |
| 1469 | +#undef movfcc /* v9 */ | |
| 1470 | +#undef movcc /* v9 */ | |
| 1471 | + | |
| 1472 | +#define FM_SF 1 /* v9 - values for fpsize */ | |
| 1473 | +#define FM_DF 2 /* v9 */ | |
| 1474 | +#define FM_QF 3 /* v9 */ | |
| 1475 | + | |
| 1476 | +#define fmovicc(opcode, fpsize, cond, flags) /* v9 */ \ | |
| 1477 | +{ opcode, F3F(2, 0x35, 0x100+fpsize)|MCOND(cond,0), F3F(~2, ~0x35, ~(0x100+fpsize))|MCOND(~cond,~0), "z,f,g", flags, v9 }, \ | |
| 1478 | +{ opcode, F3F(2, 0x35, 0x180+fpsize)|MCOND(cond,0), F3F(~2, ~0x35, ~(0x180+fpsize))|MCOND(~cond,~0), "Z,f,g", flags, v9 } | |
| 1479 | + | |
| 1480 | +#define fmovfcc(opcode, fpsize, fcond, flags) /* v9 */ \ | |
| 1481 | +{ opcode, F3F(2, 0x35, 0x000+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x000+fpsize))|MCOND(~fcond,~0), "6,f,g", flags, v9 }, \ | |
| 1482 | +{ opcode, F3F(2, 0x35, 0x040+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x040+fpsize))|MCOND(~fcond,~0), "7,f,g", flags, v9 }, \ | |
| 1483 | +{ opcode, F3F(2, 0x35, 0x080+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x080+fpsize))|MCOND(~fcond,~0), "8,f,g", flags, v9 }, \ | |
| 1484 | +{ opcode, F3F(2, 0x35, 0x0c0+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x0c0+fpsize))|MCOND(~fcond,~0), "9,f,g", flags, v9 } | |
| 1485 | + | |
| 1486 | +/* FIXME: use fmovicc/fmovfcc? */ /* v9 */ | |
| 1487 | +#define fmovcc(opcode, fpsize, cond, fcond, flags) /* v9 */ \ | |
| 1488 | +{ opcode, F3F(2, 0x35, 0x100+fpsize)|MCOND(cond,0), F3F(~2, ~0x35, ~(0x100+fpsize))|MCOND(~cond,~0), "z,f,g", flags | F_FLOAT, v9 }, \ | |
| 1489 | +{ opcode, F3F(2, 0x35, 0x000+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x000+fpsize))|MCOND(~fcond,~0), "6,f,g", flags | F_FLOAT, v9 }, \ | |
| 1490 | +{ opcode, F3F(2, 0x35, 0x180+fpsize)|MCOND(cond,0), F3F(~2, ~0x35, ~(0x180+fpsize))|MCOND(~cond,~0), "Z,f,g", flags | F_FLOAT, v9 }, \ | |
| 1491 | +{ opcode, F3F(2, 0x35, 0x040+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x040+fpsize))|MCOND(~fcond,~0), "7,f,g", flags | F_FLOAT, v9 }, \ | |
| 1492 | +{ opcode, F3F(2, 0x35, 0x080+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x080+fpsize))|MCOND(~fcond,~0), "8,f,g", flags | F_FLOAT, v9 }, \ | |
| 1493 | +{ opcode, F3F(2, 0x35, 0x0c0+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x0c0+fpsize))|MCOND(~fcond,~0), "9,f,g", flags | F_FLOAT, v9 } | |
| 1494 | + | |
| 1495 | +/* v9 */ fmovcc ("fmovda", FM_DF, CONDA, FCONDA, 0), | |
| 1496 | +/* v9 */ fmovcc ("fmovqa", FM_QF, CONDA, FCONDA, 0), | |
| 1497 | +/* v9 */ fmovcc ("fmovsa", FM_SF, CONDA, FCONDA, 0), | |
| 1498 | +/* v9 */ fmovicc ("fmovdcc", FM_DF, CONDCC, 0), | |
| 1499 | +/* v9 */ fmovicc ("fmovqcc", FM_QF, CONDCC, 0), | |
| 1500 | +/* v9 */ fmovicc ("fmovscc", FM_SF, CONDCC, 0), | |
| 1501 | +/* v9 */ fmovicc ("fmovdcs", FM_DF, CONDCS, 0), | |
| 1502 | +/* v9 */ fmovicc ("fmovqcs", FM_QF, CONDCS, 0), | |
| 1503 | +/* v9 */ fmovicc ("fmovscs", FM_SF, CONDCS, 0), | |
| 1504 | +/* v9 */ fmovcc ("fmovde", FM_DF, CONDE, FCONDE, 0), | |
| 1505 | +/* v9 */ fmovcc ("fmovqe", FM_QF, CONDE, FCONDE, 0), | |
| 1506 | +/* v9 */ fmovcc ("fmovse", FM_SF, CONDE, FCONDE, 0), | |
| 1507 | +/* v9 */ fmovcc ("fmovdg", FM_DF, CONDG, FCONDG, 0), | |
| 1508 | +/* v9 */ fmovcc ("fmovqg", FM_QF, CONDG, FCONDG, 0), | |
| 1509 | +/* v9 */ fmovcc ("fmovsg", FM_SF, CONDG, FCONDG, 0), | |
| 1510 | +/* v9 */ fmovcc ("fmovdge", FM_DF, CONDGE, FCONDGE, 0), | |
| 1511 | +/* v9 */ fmovcc ("fmovqge", FM_QF, CONDGE, FCONDGE, 0), | |
| 1512 | +/* v9 */ fmovcc ("fmovsge", FM_SF, CONDGE, FCONDGE, 0), | |
| 1513 | +/* v9 */ fmovicc ("fmovdgeu", FM_DF, CONDGEU, F_ALIAS), | |
| 1514 | +/* v9 */ fmovicc ("fmovqgeu", FM_QF, CONDGEU, F_ALIAS), | |
| 1515 | +/* v9 */ fmovicc ("fmovsgeu", FM_SF, CONDGEU, F_ALIAS), | |
| 1516 | +/* v9 */ fmovicc ("fmovdgu", FM_DF, CONDGU, 0), | |
| 1517 | +/* v9 */ fmovicc ("fmovqgu", FM_QF, CONDGU, 0), | |
| 1518 | +/* v9 */ fmovicc ("fmovsgu", FM_SF, CONDGU, 0), | |
| 1519 | +/* v9 */ fmovcc ("fmovdl", FM_DF, CONDL, FCONDL, 0), | |
| 1520 | +/* v9 */ fmovcc ("fmovql", FM_QF, CONDL, FCONDL, 0), | |
| 1521 | +/* v9 */ fmovcc ("fmovsl", FM_SF, CONDL, FCONDL, 0), | |
| 1522 | +/* v9 */ fmovcc ("fmovdle", FM_DF, CONDLE, FCONDLE, 0), | |
| 1523 | +/* v9 */ fmovcc ("fmovqle", FM_QF, CONDLE, FCONDLE, 0), | |
| 1524 | +/* v9 */ fmovcc ("fmovsle", FM_SF, CONDLE, FCONDLE, 0), | |
| 1525 | +/* v9 */ fmovicc ("fmovdleu", FM_DF, CONDLEU, 0), | |
| 1526 | +/* v9 */ fmovicc ("fmovqleu", FM_QF, CONDLEU, 0), | |
| 1527 | +/* v9 */ fmovicc ("fmovsleu", FM_SF, CONDLEU, 0), | |
| 1528 | +/* v9 */ fmovfcc ("fmovdlg", FM_DF, FCONDLG, 0), | |
| 1529 | +/* v9 */ fmovfcc ("fmovqlg", FM_QF, FCONDLG, 0), | |
| 1530 | +/* v9 */ fmovfcc ("fmovslg", FM_SF, FCONDLG, 0), | |
| 1531 | +/* v9 */ fmovicc ("fmovdlu", FM_DF, CONDLU, F_ALIAS), | |
| 1532 | +/* v9 */ fmovicc ("fmovqlu", FM_QF, CONDLU, F_ALIAS), | |
| 1533 | +/* v9 */ fmovicc ("fmovslu", FM_SF, CONDLU, F_ALIAS), | |
| 1534 | +/* v9 */ fmovcc ("fmovdn", FM_DF, CONDN, FCONDN, 0), | |
| 1535 | +/* v9 */ fmovcc ("fmovqn", FM_QF, CONDN, FCONDN, 0), | |
| 1536 | +/* v9 */ fmovcc ("fmovsn", FM_SF, CONDN, FCONDN, 0), | |
| 1537 | +/* v9 */ fmovcc ("fmovdne", FM_DF, CONDNE, FCONDNE, 0), | |
| 1538 | +/* v9 */ fmovcc ("fmovqne", FM_QF, CONDNE, FCONDNE, 0), | |
| 1539 | +/* v9 */ fmovcc ("fmovsne", FM_SF, CONDNE, FCONDNE, 0), | |
| 1540 | +/* v9 */ fmovicc ("fmovdneg", FM_DF, CONDNEG, 0), | |
| 1541 | +/* v9 */ fmovicc ("fmovqneg", FM_QF, CONDNEG, 0), | |
| 1542 | +/* v9 */ fmovicc ("fmovsneg", FM_SF, CONDNEG, 0), | |
| 1543 | +/* v9 */ fmovcc ("fmovdnz", FM_DF, CONDNZ, FCONDNZ, F_ALIAS), | |
| 1544 | +/* v9 */ fmovcc ("fmovqnz", FM_QF, CONDNZ, FCONDNZ, F_ALIAS), | |
| 1545 | +/* v9 */ fmovcc ("fmovsnz", FM_SF, CONDNZ, FCONDNZ, F_ALIAS), | |
| 1546 | +/* v9 */ fmovfcc ("fmovdo", FM_DF, FCONDO, 0), | |
| 1547 | +/* v9 */ fmovfcc ("fmovqo", FM_QF, FCONDO, 0), | |
| 1548 | +/* v9 */ fmovfcc ("fmovso", FM_SF, FCONDO, 0), | |
| 1549 | +/* v9 */ fmovicc ("fmovdpos", FM_DF, CONDPOS, 0), | |
| 1550 | +/* v9 */ fmovicc ("fmovqpos", FM_QF, CONDPOS, 0), | |
| 1551 | +/* v9 */ fmovicc ("fmovspos", FM_SF, CONDPOS, 0), | |
| 1552 | +/* v9 */ fmovfcc ("fmovdu", FM_DF, FCONDU, 0), | |
| 1553 | +/* v9 */ fmovfcc ("fmovqu", FM_QF, FCONDU, 0), | |
| 1554 | +/* v9 */ fmovfcc ("fmovsu", FM_SF, FCONDU, 0), | |
| 1555 | +/* v9 */ fmovfcc ("fmovdue", FM_DF, FCONDUE, 0), | |
| 1556 | +/* v9 */ fmovfcc ("fmovque", FM_QF, FCONDUE, 0), | |
| 1557 | +/* v9 */ fmovfcc ("fmovsue", FM_SF, FCONDUE, 0), | |
| 1558 | +/* v9 */ fmovfcc ("fmovdug", FM_DF, FCONDUG, 0), | |
| 1559 | +/* v9 */ fmovfcc ("fmovqug", FM_QF, FCONDUG, 0), | |
| 1560 | +/* v9 */ fmovfcc ("fmovsug", FM_SF, FCONDUG, 0), | |
| 1561 | +/* v9 */ fmovfcc ("fmovduge", FM_DF, FCONDUGE, 0), | |
| 1562 | +/* v9 */ fmovfcc ("fmovquge", FM_QF, FCONDUGE, 0), | |
| 1563 | +/* v9 */ fmovfcc ("fmovsuge", FM_SF, FCONDUGE, 0), | |
| 1564 | +/* v9 */ fmovfcc ("fmovdul", FM_DF, FCONDUL, 0), | |
| 1565 | +/* v9 */ fmovfcc ("fmovqul", FM_QF, FCONDUL, 0), | |
| 1566 | +/* v9 */ fmovfcc ("fmovsul", FM_SF, FCONDUL, 0), | |
| 1567 | +/* v9 */ fmovfcc ("fmovdule", FM_DF, FCONDULE, 0), | |
| 1568 | +/* v9 */ fmovfcc ("fmovqule", FM_QF, FCONDULE, 0), | |
| 1569 | +/* v9 */ fmovfcc ("fmovsule", FM_SF, FCONDULE, 0), | |
| 1570 | +/* v9 */ fmovicc ("fmovdvc", FM_DF, CONDVC, 0), | |
| 1571 | +/* v9 */ fmovicc ("fmovqvc", FM_QF, CONDVC, 0), | |
| 1572 | +/* v9 */ fmovicc ("fmovsvc", FM_SF, CONDVC, 0), | |
| 1573 | +/* v9 */ fmovicc ("fmovdvs", FM_DF, CONDVS, 0), | |
| 1574 | +/* v9 */ fmovicc ("fmovqvs", FM_QF, CONDVS, 0), | |
| 1575 | +/* v9 */ fmovicc ("fmovsvs", FM_SF, CONDVS, 0), | |
| 1576 | +/* v9 */ fmovcc ("fmovdz", FM_DF, CONDZ, FCONDZ, F_ALIAS), | |
| 1577 | +/* v9 */ fmovcc ("fmovqz", FM_QF, CONDZ, FCONDZ, F_ALIAS), | |
| 1578 | +/* v9 */ fmovcc ("fmovsz", FM_SF, CONDZ, FCONDZ, F_ALIAS), | |
| 1579 | + | |
| 1580 | +#undef fmovicc /* v9 */ | |
| 1581 | +#undef fmovfcc /* v9 */ | |
| 1582 | +#undef fmovcc /* v9 */ | |
| 1583 | +#undef FM_DF /* v9 */ | |
| 1584 | +#undef FM_QF /* v9 */ | |
| 1585 | +#undef FM_SF /* v9 */ | |
| 1586 | + | |
| 1587 | +/* Coprocessor branches. */ | |
| 1588 | +#define CBR(opcode, mask, lose, flags, arch) \ | |
| 1589 | + { opcode, (mask), ANNUL|(lose), "l", flags|F_DELAYED, arch }, \ | |
| 1590 | + { opcode, (mask)|ANNUL, (lose), ",a l", flags|F_DELAYED, arch } | |
| 1591 | + | |
| 1592 | +/* Floating point branches. */ | |
| 1593 | +#define FBR(opcode, mask, lose, flags) \ | |
| 1594 | + { opcode, (mask), ANNUL|(lose), "l", flags|F_DELAYED|F_FBR, v6 }, \ | |
| 1595 | + { opcode, (mask)|ANNUL, (lose), ",a l", flags|F_DELAYED|F_FBR, v6 } | |
| 1596 | + | |
| 1597 | +/* V9 extended floating point branches. */ | |
| 1598 | +#define FBRX(opcode, mask, lose, flags) /* v9 */ \ | |
| 1599 | + { opcode, FBFCC(0)|(mask)|BPRED, ANNUL|FBFCC(~0)|(lose), "6,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1600 | + { opcode, FBFCC(0)|(mask)|BPRED, ANNUL|FBFCC(~0)|(lose), ",T 6,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1601 | + { opcode, FBFCC(0)|(mask)|BPRED|ANNUL, FBFCC(~0)|(lose), ",a 6,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1602 | + { opcode, FBFCC(0)|(mask)|BPRED|ANNUL, FBFCC(~0)|(lose), ",a,T 6,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1603 | + { opcode, FBFCC(0)|(mask), ANNUL|BPRED|FBFCC(~0)|(lose), ",N 6,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1604 | + { opcode, FBFCC(0)|(mask)|ANNUL, BPRED|FBFCC(~0)|(lose), ",a,N 6,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1605 | + { opcode, FBFCC(1)|(mask)|BPRED, ANNUL|FBFCC(~1)|(lose), "7,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1606 | + { opcode, FBFCC(1)|(mask)|BPRED, ANNUL|FBFCC(~1)|(lose), ",T 7,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1607 | + { opcode, FBFCC(1)|(mask)|BPRED|ANNUL, FBFCC(~1)|(lose), ",a 7,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1608 | + { opcode, FBFCC(1)|(mask)|BPRED|ANNUL, FBFCC(~1)|(lose), ",a,T 7,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1609 | + { opcode, FBFCC(1)|(mask), ANNUL|BPRED|FBFCC(~1)|(lose), ",N 7,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1610 | + { opcode, FBFCC(1)|(mask)|ANNUL, BPRED|FBFCC(~1)|(lose), ",a,N 7,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1611 | + { opcode, FBFCC(2)|(mask)|BPRED, ANNUL|FBFCC(~2)|(lose), "8,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1612 | + { opcode, FBFCC(2)|(mask)|BPRED, ANNUL|FBFCC(~2)|(lose), ",T 8,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1613 | + { opcode, FBFCC(2)|(mask)|BPRED|ANNUL, FBFCC(~2)|(lose), ",a 8,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1614 | + { opcode, FBFCC(2)|(mask)|BPRED|ANNUL, FBFCC(~2)|(lose), ",a,T 8,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1615 | + { opcode, FBFCC(2)|(mask), ANNUL|BPRED|FBFCC(~2)|(lose), ",N 8,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1616 | + { opcode, FBFCC(2)|(mask)|ANNUL, BPRED|FBFCC(~2)|(lose), ",a,N 8,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1617 | + { opcode, FBFCC(3)|(mask)|BPRED, ANNUL|FBFCC(~3)|(lose), "9,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1618 | + { opcode, FBFCC(3)|(mask)|BPRED, ANNUL|FBFCC(~3)|(lose), ",T 9,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1619 | + { opcode, FBFCC(3)|(mask)|BPRED|ANNUL, FBFCC(~3)|(lose), ",a 9,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1620 | + { opcode, FBFCC(3)|(mask)|BPRED|ANNUL, FBFCC(~3)|(lose), ",a,T 9,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1621 | + { opcode, FBFCC(3)|(mask), ANNUL|BPRED|FBFCC(~3)|(lose), ",N 9,G", flags|F_DELAYED|F_FBR, v9 }, \ | |
| 1622 | + { opcode, FBFCC(3)|(mask)|ANNUL, BPRED|FBFCC(~3)|(lose), ",a,N 9,G", flags|F_DELAYED|F_FBR, v9 } | |
| 1623 | + | |
| 1624 | +/* v9: We must put `FBRX' before `FBR', to ensure that we never match | |
| 1625 | + v9: something against an expression unless it is an expression. Otherwise, | |
| 1626 | + v9: we end up with undefined symbol tables entries, because they get added, | |
| 1627 | + v9: but are not deleted if the pattern fails to match. */ | |
| 1628 | + | |
| 1629 | +#define CONDFC(fop, cop, mask, flags) \ | |
| 1630 | + FBRX(fop, F2(0, 5)|COND(mask), F2(~0, ~5)|COND(~(mask)), flags), /* v9 */ \ | |
| 1631 | + FBR(fop, F2(0, 6)|COND(mask), F2(~0, ~6)|COND(~(mask)), flags), \ | |
| 1632 | + CBR(cop, F2(0, 7)|COND(mask), F2(~0, ~7)|COND(~(mask)), flags, v6notlet) | |
| 1633 | + | |
| 1634 | +#define CONDFCL(fop, cop, mask, flags) \ | |
| 1635 | + FBRX(fop, F2(0, 5)|COND(mask), F2(~0, ~5)|COND(~(mask)), flags), /* v9 */ \ | |
| 1636 | + FBR(fop, F2(0, 6)|COND(mask), F2(~0, ~6)|COND(~(mask)), flags), \ | |
| 1637 | + CBR(cop, F2(0, 7)|COND(mask), F2(~0, ~7)|COND(~(mask)), flags, v6) | |
| 1638 | + | |
| 1639 | +#define CONDF(fop, mask, flags) \ | |
| 1640 | + FBRX(fop, F2(0, 5)|COND(mask), F2(~0, ~5)|COND(~(mask)), flags), /* v9 */ \ | |
| 1641 | + FBR(fop, F2(0, 6)|COND(mask), F2(~0, ~6)|COND(~(mask)), flags) | |
| 1642 | + | |
| 1643 | +CONDFC ("fb", "cb", 0x8, F_UNBR), | |
| 1644 | +CONDFCL ("fba", "cba", 0x8, F_UNBR|F_ALIAS), | |
| 1645 | +CONDFC ("fbe", "cb0", 0x9, F_CONDBR), | |
| 1646 | +CONDF ("fbz", 0x9, F_CONDBR|F_ALIAS), | |
| 1647 | +CONDFC ("fbg", "cb2", 0x6, F_CONDBR), | |
| 1648 | +CONDFC ("fbge", "cb02", 0xb, F_CONDBR), | |
| 1649 | +CONDFC ("fbl", "cb1", 0x4, F_CONDBR), | |
| 1650 | +CONDFC ("fble", "cb01", 0xd, F_CONDBR), | |
| 1651 | +CONDFC ("fblg", "cb12", 0x2, F_CONDBR), | |
| 1652 | +CONDFCL ("fbn", "cbn", 0x0, F_UNBR), | |
| 1653 | +CONDFC ("fbne", "cb123", 0x1, F_CONDBR), | |
| 1654 | +CONDF ("fbnz", 0x1, F_CONDBR|F_ALIAS), | |
| 1655 | +CONDFC ("fbo", "cb012", 0xf, F_CONDBR), | |
| 1656 | +CONDFC ("fbu", "cb3", 0x7, F_CONDBR), | |
| 1657 | +CONDFC ("fbue", "cb03", 0xa, F_CONDBR), | |
| 1658 | +CONDFC ("fbug", "cb23", 0x5, F_CONDBR), | |
| 1659 | +CONDFC ("fbuge", "cb023", 0xc, F_CONDBR), | |
| 1660 | +CONDFC ("fbul", "cb13", 0x3, F_CONDBR), | |
| 1661 | +CONDFC ("fbule", "cb013", 0xe, F_CONDBR), | |
| 1662 | + | |
| 1663 | +#undef CONDFC | |
| 1664 | +#undef CONDFCL | |
| 1665 | +#undef CONDF | |
| 1666 | +#undef CBR | |
| 1667 | +#undef FBR | |
| 1668 | +#undef FBRX /* v9 */ | |
| 1669 | + | |
| 1670 | +{ "jmp", F3(2, 0x38, 0), F3(~2, ~0x38, ~0)|RD_G0|ASI(~0), "1+2", F_UNBR|F_DELAYED, v6 }, /* jmpl rs1+rs2,%g0 */ | |
| 1671 | +{ "jmp", F3(2, 0x38, 0), F3(~2, ~0x38, ~0)|RD_G0|ASI_RS2(~0), "1", F_UNBR|F_DELAYED, v6 }, /* jmpl rs1+%g0,%g0 */ | |
| 1672 | +{ "jmp", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|RD_G0, "1+i", F_UNBR|F_DELAYED, v6 }, /* jmpl rs1+i,%g0 */ | |
| 1673 | +{ "jmp", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|RD_G0, "i+1", F_UNBR|F_DELAYED, v6 }, /* jmpl i+rs1,%g0 */ | |
| 1674 | +{ "jmp", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|RD_G0|RS1_G0, "i", F_UNBR|F_DELAYED, v6 }, /* jmpl %g0+i,%g0 */ | |
| 1675 | +{ "jmp", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|RD_G0|SIMM13(~0), "1", F_UNBR|F_DELAYED, v6 }, /* jmpl rs1+0,%g0 */ | |
| 1676 | + | |
| 1677 | +{ "nop", F2(0, 4), 0xfeffffff, "", 0, v6 }, /* sethi 0, %g0 */ | |
| 1678 | + | |
| 1679 | +{ "set", F2(0x0, 0x4), F2(~0x0, ~0x4), "S0,d", F_ALIAS, v6 }, | |
| 1680 | +{ "setuw", F2(0x0, 0x4), F2(~0x0, ~0x4), "S0,d", F_ALIAS, v9 }, | |
| 1681 | +{ "setsw", F2(0x0, 0x4), F2(~0x0, ~0x4), "S0,d", F_ALIAS, v9 }, | |
| 1682 | +{ "setx", F2(0x0, 0x4), F2(~0x0, ~0x4), "S0,1,d", F_ALIAS, v9 }, | |
| 1683 | + | |
| 1684 | +{ "sethi", F2(0x0, 0x4), F2(~0x0, ~0x4), "h,d", 0, v6 }, | |
| 1685 | + | |
| 1686 | +{ "taddcc", F3(2, 0x20, 0), F3(~2, ~0x20, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1687 | +{ "taddcc", F3(2, 0x20, 1), F3(~2, ~0x20, ~1), "1,i,d", 0, v6 }, | |
| 1688 | +{ "taddcc", F3(2, 0x20, 1), F3(~2, ~0x20, ~1), "i,1,d", 0, v6 }, | |
| 1689 | +{ "taddcctv", F3(2, 0x22, 0), F3(~2, ~0x22, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1690 | +{ "taddcctv", F3(2, 0x22, 1), F3(~2, ~0x22, ~1), "1,i,d", 0, v6 }, | |
| 1691 | +{ "taddcctv", F3(2, 0x22, 1), F3(~2, ~0x22, ~1), "i,1,d", 0, v6 }, | |
| 1692 | + | |
| 1693 | +{ "tsubcc", F3(2, 0x21, 0), F3(~2, ~0x21, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1694 | +{ "tsubcc", F3(2, 0x21, 1), F3(~2, ~0x21, ~1), "1,i,d", 0, v6 }, | |
| 1695 | +{ "tsubcctv", F3(2, 0x23, 0), F3(~2, ~0x23, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1696 | +{ "tsubcctv", F3(2, 0x23, 1), F3(~2, ~0x23, ~1), "1,i,d", 0, v6 }, | |
| 1697 | + | |
| 1698 | +{ "unimp", F2(0x0, 0x0), 0xffc00000, "n", 0, v6notv9 }, | |
| 1699 | +{ "illtrap", F2(0, 0), F2(~0, ~0)|RD_G0, "n", 0, v9 }, | |
| 1700 | + | |
| 1701 | +/* This *is* a commutative instruction. */ | |
| 1702 | +{ "xnor", F3(2, 0x07, 0), F3(~2, ~0x07, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1703 | +{ "xnor", F3(2, 0x07, 1), F3(~2, ~0x07, ~1), "1,i,d", 0, v6 }, | |
| 1704 | +{ "xnor", F3(2, 0x07, 1), F3(~2, ~0x07, ~1), "i,1,d", 0, v6 }, | |
| 1705 | +/* This *is* a commutative instruction. */ | |
| 1706 | +{ "xnorcc", F3(2, 0x17, 0), F3(~2, ~0x17, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1707 | +{ "xnorcc", F3(2, 0x17, 1), F3(~2, ~0x17, ~1), "1,i,d", 0, v6 }, | |
| 1708 | +{ "xnorcc", F3(2, 0x17, 1), F3(~2, ~0x17, ~1), "i,1,d", 0, v6 }, | |
| 1709 | +{ "xor", F3(2, 0x03, 0), F3(~2, ~0x03, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1710 | +{ "xor", F3(2, 0x03, 1), F3(~2, ~0x03, ~1), "1,i,d", 0, v6 }, | |
| 1711 | +{ "xor", F3(2, 0x03, 1), F3(~2, ~0x03, ~1), "i,1,d", 0, v6 }, | |
| 1712 | +{ "xorcc", F3(2, 0x13, 0), F3(~2, ~0x13, ~0)|ASI(~0), "1,2,d", 0, v6 }, | |
| 1713 | +{ "xorcc", F3(2, 0x13, 1), F3(~2, ~0x13, ~1), "1,i,d", 0, v6 }, | |
| 1714 | +{ "xorcc", F3(2, 0x13, 1), F3(~2, ~0x13, ~1), "i,1,d", 0, v6 }, | |
| 1715 | + | |
| 1716 | +{ "not", F3(2, 0x07, 0), F3(~2, ~0x07, ~0)|ASI(~0), "1,d", F_ALIAS, v6 }, /* xnor rs1,%0,rd */ | |
| 1717 | +{ "not", F3(2, 0x07, 0), F3(~2, ~0x07, ~0)|ASI(~0), "r", F_ALIAS, v6 }, /* xnor rd,%0,rd */ | |
| 1718 | + | |
| 1719 | +{ "btog", F3(2, 0x03, 0), F3(~2, ~0x03, ~0)|ASI(~0), "2,r", F_ALIAS, v6 }, /* xor rd,rs2,rd */ | |
| 1720 | +{ "btog", F3(2, 0x03, 1), F3(~2, ~0x03, ~1), "i,r", F_ALIAS, v6 }, /* xor rd,i,rd */ | |
| 1721 | + | |
| 1722 | +/* FPop1 and FPop2 are not instructions. Don't accept them. */ | |
| 1723 | + | |
| 1724 | +{ "fdtoi", F3F(2, 0x34, 0x0d2), F3F(~2, ~0x34, ~0x0d2)|RS1_G0, "B,g", F_FLOAT, v6 }, | |
| 1725 | +{ "fstoi", F3F(2, 0x34, 0x0d1), F3F(~2, ~0x34, ~0x0d1)|RS1_G0, "f,g", F_FLOAT, v6 }, | |
| 1726 | +{ "fqtoi", F3F(2, 0x34, 0x0d3), F3F(~2, ~0x34, ~0x0d3)|RS1_G0, "R,g", F_FLOAT, v8 }, | |
| 1727 | + | |
| 1728 | +{ "fdtox", F3F(2, 0x34, 0x082), F3F(~2, ~0x34, ~0x082)|RS1_G0, "B,g", F_FLOAT, v9 }, | |
| 1729 | +{ "fstox", F3F(2, 0x34, 0x081), F3F(~2, ~0x34, ~0x081)|RS1_G0, "f,g", F_FLOAT, v9 }, | |
| 1730 | +{ "fqtox", F3F(2, 0x34, 0x083), F3F(~2, ~0x34, ~0x083)|RS1_G0, "R,g", F_FLOAT, v9 }, | |
| 1731 | + | |
| 1732 | +{ "fitod", F3F(2, 0x34, 0x0c8), F3F(~2, ~0x34, ~0x0c8)|RS1_G0, "f,H", F_FLOAT, v6 }, | |
| 1733 | +{ "fitos", F3F(2, 0x34, 0x0c4), F3F(~2, ~0x34, ~0x0c4)|RS1_G0, "f,g", F_FLOAT, v6 }, | |
| 1734 | +{ "fitoq", F3F(2, 0x34, 0x0cc), F3F(~2, ~0x34, ~0x0cc)|RS1_G0, "f,J", F_FLOAT, v8 }, | |
| 1735 | + | |
| 1736 | +{ "fxtod", F3F(2, 0x34, 0x088), F3F(~2, ~0x34, ~0x088)|RS1_G0, "f,H", F_FLOAT, v9 }, | |
| 1737 | +{ "fxtos", F3F(2, 0x34, 0x084), F3F(~2, ~0x34, ~0x084)|RS1_G0, "f,g", F_FLOAT, v9 }, | |
| 1738 | +{ "fxtoq", F3F(2, 0x34, 0x08c), F3F(~2, ~0x34, ~0x08c)|RS1_G0, "f,J", F_FLOAT, v9 }, | |
| 1739 | + | |
| 1740 | +{ "fdtoq", F3F(2, 0x34, 0x0ce), F3F(~2, ~0x34, ~0x0ce)|RS1_G0, "B,J", F_FLOAT, v8 }, | |
| 1741 | +{ "fdtos", F3F(2, 0x34, 0x0c6), F3F(~2, ~0x34, ~0x0c6)|RS1_G0, "B,g", F_FLOAT, v6 }, | |
| 1742 | +{ "fqtod", F3F(2, 0x34, 0x0cb), F3F(~2, ~0x34, ~0x0cb)|RS1_G0, "R,H", F_FLOAT, v8 }, | |
| 1743 | +{ "fqtos", F3F(2, 0x34, 0x0c7), F3F(~2, ~0x34, ~0x0c7)|RS1_G0, "R,g", F_FLOAT, v8 }, | |
| 1744 | +{ "fstod", F3F(2, 0x34, 0x0c9), F3F(~2, ~0x34, ~0x0c9)|RS1_G0, "f,H", F_FLOAT, v6 }, | |
| 1745 | +{ "fstoq", F3F(2, 0x34, 0x0cd), F3F(~2, ~0x34, ~0x0cd)|RS1_G0, "f,J", F_FLOAT, v8 }, | |
| 1746 | + | |
| 1747 | +{ "fdivd", F3F(2, 0x34, 0x04e), F3F(~2, ~0x34, ~0x04e), "v,B,H", F_FLOAT, v6 }, | |
| 1748 | +{ "fdivq", F3F(2, 0x34, 0x04f), F3F(~2, ~0x34, ~0x04f), "V,R,J", F_FLOAT, v8 }, | |
| 1749 | +{ "fdivx", F3F(2, 0x34, 0x04f), F3F(~2, ~0x34, ~0x04f), "V,R,J", F_FLOAT|F_ALIAS, v8 }, | |
| 1750 | +{ "fdivs", F3F(2, 0x34, 0x04d), F3F(~2, ~0x34, ~0x04d), "e,f,g", F_FLOAT, v6 }, | |
| 1751 | +{ "fmuld", F3F(2, 0x34, 0x04a), F3F(~2, ~0x34, ~0x04a), "v,B,H", F_FLOAT, v6 }, | |
| 1752 | +{ "fmulq", F3F(2, 0x34, 0x04b), F3F(~2, ~0x34, ~0x04b), "V,R,J", F_FLOAT, v8 }, | |
| 1753 | +{ "fmulx", F3F(2, 0x34, 0x04b), F3F(~2, ~0x34, ~0x04b), "V,R,J", F_FLOAT|F_ALIAS, v8 }, | |
| 1754 | +{ "fmuls", F3F(2, 0x34, 0x049), F3F(~2, ~0x34, ~0x049), "e,f,g", F_FLOAT, v6 }, | |
| 1755 | + | |
| 1756 | +{ "fdmulq", F3F(2, 0x34, 0x06e), F3F(~2, ~0x34, ~0x06e), "v,B,J", F_FLOAT, v8 }, | |
| 1757 | +{ "fdmulx", F3F(2, 0x34, 0x06e), F3F(~2, ~0x34, ~0x06e), "v,B,J", F_FLOAT|F_ALIAS, v8 }, | |
| 1758 | +{ "fsmuld", F3F(2, 0x34, 0x069), F3F(~2, ~0x34, ~0x069), "e,f,H", F_FLOAT, v8 }, | |
| 1759 | + | |
| 1760 | +{ "fsqrtd", F3F(2, 0x34, 0x02a), F3F(~2, ~0x34, ~0x02a)|RS1_G0, "B,H", F_FLOAT, v7 }, | |
| 1761 | +{ "fsqrtq", F3F(2, 0x34, 0x02b), F3F(~2, ~0x34, ~0x02b)|RS1_G0, "R,J", F_FLOAT, v8 }, | |
| 1762 | +{ "fsqrtx", F3F(2, 0x34, 0x02b), F3F(~2, ~0x34, ~0x02b)|RS1_G0, "R,J", F_FLOAT|F_ALIAS, v8 }, | |
| 1763 | +{ "fsqrts", F3F(2, 0x34, 0x029), F3F(~2, ~0x34, ~0x029)|RS1_G0, "f,g", F_FLOAT, v7 }, | |
| 1764 | + | |
| 1765 | +{ "fabsd", F3F(2, 0x34, 0x00a), F3F(~2, ~0x34, ~0x00a)|RS1_G0, "B,H", F_FLOAT, v9 }, | |
| 1766 | +{ "fabsq", F3F(2, 0x34, 0x00b), F3F(~2, ~0x34, ~0x00b)|RS1_G0, "R,J", F_FLOAT, v9 }, | |
| 1767 | +{ "fabsx", F3F(2, 0x34, 0x00b), F3F(~2, ~0x34, ~0x00b)|RS1_G0, "R,J", F_FLOAT|F_ALIAS, v9 }, | |
| 1768 | +{ "fabss", F3F(2, 0x34, 0x009), F3F(~2, ~0x34, ~0x009)|RS1_G0, "f,g", F_FLOAT, v6 }, | |
| 1769 | +{ "fmovd", F3F(2, 0x34, 0x002), F3F(~2, ~0x34, ~0x002)|RS1_G0, "B,H", F_FLOAT, v9 }, | |
| 1770 | +{ "fmovq", F3F(2, 0x34, 0x003), F3F(~2, ~0x34, ~0x003)|RS1_G0, "R,J", F_FLOAT, v9 }, | |
| 1771 | +{ "fmovx", F3F(2, 0x34, 0x003), F3F(~2, ~0x34, ~0x003)|RS1_G0, "R,J", F_FLOAT|F_ALIAS, v9 }, | |
| 1772 | +{ "fmovs", F3F(2, 0x34, 0x001), F3F(~2, ~0x34, ~0x001)|RS1_G0, "f,g", F_FLOAT, v6 }, | |
| 1773 | +{ "fnegd", F3F(2, 0x34, 0x006), F3F(~2, ~0x34, ~0x006)|RS1_G0, "B,H", F_FLOAT, v9 }, | |
| 1774 | +{ "fnegq", F3F(2, 0x34, 0x007), F3F(~2, ~0x34, ~0x007)|RS1_G0, "R,J", F_FLOAT, v9 }, | |
| 1775 | +{ "fnegx", F3F(2, 0x34, 0x007), F3F(~2, ~0x34, ~0x007)|RS1_G0, "R,J", F_FLOAT|F_ALIAS, v9 }, | |
| 1776 | +{ "fnegs", F3F(2, 0x34, 0x005), F3F(~2, ~0x34, ~0x005)|RS1_G0, "f,g", F_FLOAT, v6 }, | |
| 1777 | + | |
| 1778 | +{ "faddd", F3F(2, 0x34, 0x042), F3F(~2, ~0x34, ~0x042), "v,B,H", F_FLOAT, v6 }, | |
| 1779 | +{ "faddq", F3F(2, 0x34, 0x043), F3F(~2, ~0x34, ~0x043), "V,R,J", F_FLOAT, v8 }, | |
| 1780 | +{ "faddx", F3F(2, 0x34, 0x043), F3F(~2, ~0x34, ~0x043), "V,R,J", F_FLOAT|F_ALIAS, v8 }, | |
| 1781 | +{ "fadds", F3F(2, 0x34, 0x041), F3F(~2, ~0x34, ~0x041), "e,f,g", F_FLOAT, v6 }, | |
| 1782 | +{ "fsubd", F3F(2, 0x34, 0x046), F3F(~2, ~0x34, ~0x046), "v,B,H", F_FLOAT, v6 }, | |
| 1783 | +{ "fsubq", F3F(2, 0x34, 0x047), F3F(~2, ~0x34, ~0x047), "V,R,J", F_FLOAT, v8 }, | |
| 1784 | +{ "fsubx", F3F(2, 0x34, 0x047), F3F(~2, ~0x34, ~0x047), "V,R,J", F_FLOAT|F_ALIAS, v8 }, | |
| 1785 | +{ "fsubs", F3F(2, 0x34, 0x045), F3F(~2, ~0x34, ~0x045), "e,f,g", F_FLOAT, v6 }, | |
| 1786 | + | |
| 1787 | +#define CMPFCC(x) (((x)&0x3)<<25) | |
| 1788 | + | |
| 1789 | +{ "fcmpd", F3F(2, 0x35, 0x052), F3F(~2, ~0x35, ~0x052)|RD_G0, "v,B", F_FLOAT, v6 }, | |
| 1790 | +{ "fcmpd", CMPFCC(0)|F3F(2, 0x35, 0x052), CMPFCC(~0)|F3F(~2, ~0x35, ~0x052), "6,v,B", F_FLOAT, v9 }, | |
| 1791 | +{ "fcmpd", CMPFCC(1)|F3F(2, 0x35, 0x052), CMPFCC(~1)|F3F(~2, ~0x35, ~0x052), "7,v,B", F_FLOAT, v9 }, | |
| 1792 | +{ "fcmpd", CMPFCC(2)|F3F(2, 0x35, 0x052), CMPFCC(~2)|F3F(~2, ~0x35, ~0x052), "8,v,B", F_FLOAT, v9 }, | |
| 1793 | +{ "fcmpd", CMPFCC(3)|F3F(2, 0x35, 0x052), CMPFCC(~3)|F3F(~2, ~0x35, ~0x052), "9,v,B", F_FLOAT, v9 }, | |
| 1794 | +{ "fcmped", F3F(2, 0x35, 0x056), F3F(~2, ~0x35, ~0x056)|RD_G0, "v,B", F_FLOAT, v6 }, | |
| 1795 | +{ "fcmped", CMPFCC(0)|F3F(2, 0x35, 0x056), CMPFCC(~0)|F3F(~2, ~0x35, ~0x056), "6,v,B", F_FLOAT, v9 }, | |
| 1796 | +{ "fcmped", CMPFCC(1)|F3F(2, 0x35, 0x056), CMPFCC(~1)|F3F(~2, ~0x35, ~0x056), "7,v,B", F_FLOAT, v9 }, | |
| 1797 | +{ "fcmped", CMPFCC(2)|F3F(2, 0x35, 0x056), CMPFCC(~2)|F3F(~2, ~0x35, ~0x056), "8,v,B", F_FLOAT, v9 }, | |
| 1798 | +{ "fcmped", CMPFCC(3)|F3F(2, 0x35, 0x056), CMPFCC(~3)|F3F(~2, ~0x35, ~0x056), "9,v,B", F_FLOAT, v9 }, | |
| 1799 | +{ "fcmpq", F3F(2, 0x35, 0x053), F3F(~2, ~0x35, ~0x053)|RD_G0, "V,R", F_FLOAT, v8 }, | |
| 1800 | +{ "fcmpq", CMPFCC(0)|F3F(2, 0x35, 0x053), CMPFCC(~0)|F3F(~2, ~0x35, ~0x053), "6,V,R", F_FLOAT, v9 }, | |
| 1801 | +{ "fcmpq", CMPFCC(1)|F3F(2, 0x35, 0x053), CMPFCC(~1)|F3F(~2, ~0x35, ~0x053), "7,V,R", F_FLOAT, v9 }, | |
| 1802 | +{ "fcmpq", CMPFCC(2)|F3F(2, 0x35, 0x053), CMPFCC(~2)|F3F(~2, ~0x35, ~0x053), "8,V,R", F_FLOAT, v9 }, | |
| 1803 | +{ "fcmpq", CMPFCC(3)|F3F(2, 0x35, 0x053), CMPFCC(~3)|F3F(~2, ~0x35, ~0x053), "9,V,R", F_FLOAT, v9 }, | |
| 1804 | +{ "fcmpeq", F3F(2, 0x35, 0x057), F3F(~2, ~0x35, ~0x057)|RD_G0, "V,R", F_FLOAT, v8 }, | |
| 1805 | +{ "fcmpeq", CMPFCC(0)|F3F(2, 0x35, 0x057), CMPFCC(~0)|F3F(~2, ~0x35, ~0x057), "6,V,R", F_FLOAT, v9 }, | |
| 1806 | +{ "fcmpeq", CMPFCC(1)|F3F(2, 0x35, 0x057), CMPFCC(~1)|F3F(~2, ~0x35, ~0x057), "7,V,R", F_FLOAT, v9 }, | |
| 1807 | +{ "fcmpeq", CMPFCC(2)|F3F(2, 0x35, 0x057), CMPFCC(~2)|F3F(~2, ~0x35, ~0x057), "8,V,R", F_FLOAT, v9 }, | |
| 1808 | +{ "fcmpeq", CMPFCC(3)|F3F(2, 0x35, 0x057), CMPFCC(~3)|F3F(~2, ~0x35, ~0x057), "9,V,R", F_FLOAT, v9 }, | |
| 1809 | +{ "fcmpx", F3F(2, 0x35, 0x053), F3F(~2, ~0x35, ~0x053)|RD_G0, "V,R", F_FLOAT|F_ALIAS, v8 }, | |
| 1810 | +{ "fcmpx", CMPFCC(0)|F3F(2, 0x35, 0x053), CMPFCC(~0)|F3F(~2, ~0x35, ~0x053), "6,V,R", F_FLOAT|F_ALIAS, v9 }, | |
| 1811 | +{ "fcmpx", CMPFCC(1)|F3F(2, 0x35, 0x053), CMPFCC(~1)|F3F(~2, ~0x35, ~0x053), "7,V,R", F_FLOAT|F_ALIAS, v9 }, | |
| 1812 | +{ "fcmpx", CMPFCC(2)|F3F(2, 0x35, 0x053), CMPFCC(~2)|F3F(~2, ~0x35, ~0x053), "8,V,R", F_FLOAT|F_ALIAS, v9 }, | |
| 1813 | +{ "fcmpx", CMPFCC(3)|F3F(2, 0x35, 0x053), CMPFCC(~3)|F3F(~2, ~0x35, ~0x053), "9,V,R", F_FLOAT|F_ALIAS, v9 }, | |
| 1814 | +{ "fcmpex", F3F(2, 0x35, 0x057), F3F(~2, ~0x35, ~0x057)|RD_G0, "V,R", F_FLOAT|F_ALIAS, v8 }, | |
| 1815 | +{ "fcmpex", CMPFCC(0)|F3F(2, 0x35, 0x057), CMPFCC(~0)|F3F(~2, ~0x35, ~0x057), "6,V,R", F_FLOAT|F_ALIAS, v9 }, | |
| 1816 | +{ "fcmpex", CMPFCC(1)|F3F(2, 0x35, 0x057), CMPFCC(~1)|F3F(~2, ~0x35, ~0x057), "7,V,R", F_FLOAT|F_ALIAS, v9 }, | |
| 1817 | +{ "fcmpex", CMPFCC(2)|F3F(2, 0x35, 0x057), CMPFCC(~2)|F3F(~2, ~0x35, ~0x057), "8,V,R", F_FLOAT|F_ALIAS, v9 }, | |
| 1818 | +{ "fcmpex", CMPFCC(3)|F3F(2, 0x35, 0x057), CMPFCC(~3)|F3F(~2, ~0x35, ~0x057), "9,V,R", F_FLOAT|F_ALIAS, v9 }, | |
| 1819 | +{ "fcmps", F3F(2, 0x35, 0x051), F3F(~2, ~0x35, ~0x051)|RD_G0, "e,f", F_FLOAT, v6 }, | |
| 1820 | +{ "fcmps", CMPFCC(0)|F3F(2, 0x35, 0x051), CMPFCC(~0)|F3F(~2, ~0x35, ~0x051), "6,e,f", F_FLOAT, v9 }, | |
| 1821 | +{ "fcmps", CMPFCC(1)|F3F(2, 0x35, 0x051), CMPFCC(~1)|F3F(~2, ~0x35, ~0x051), "7,e,f", F_FLOAT, v9 }, | |
| 1822 | +{ "fcmps", CMPFCC(2)|F3F(2, 0x35, 0x051), CMPFCC(~2)|F3F(~2, ~0x35, ~0x051), "8,e,f", F_FLOAT, v9 }, | |
| 1823 | +{ "fcmps", CMPFCC(3)|F3F(2, 0x35, 0x051), CMPFCC(~3)|F3F(~2, ~0x35, ~0x051), "9,e,f", F_FLOAT, v9 }, | |
| 1824 | +{ "fcmpes", F3F(2, 0x35, 0x055), F3F(~2, ~0x35, ~0x055)|RD_G0, "e,f", F_FLOAT, v6 }, | |
| 1825 | +{ "fcmpes", CMPFCC(0)|F3F(2, 0x35, 0x055), CMPFCC(~0)|F3F(~2, ~0x35, ~0x055), "6,e,f", F_FLOAT, v9 }, | |
| 1826 | +{ "fcmpes", CMPFCC(1)|F3F(2, 0x35, 0x055), CMPFCC(~1)|F3F(~2, ~0x35, ~0x055), "7,e,f", F_FLOAT, v9 }, | |
| 1827 | +{ "fcmpes", CMPFCC(2)|F3F(2, 0x35, 0x055), CMPFCC(~2)|F3F(~2, ~0x35, ~0x055), "8,e,f", F_FLOAT, v9 }, | |
| 1828 | +{ "fcmpes", CMPFCC(3)|F3F(2, 0x35, 0x055), CMPFCC(~3)|F3F(~2, ~0x35, ~0x055), "9,e,f", F_FLOAT, v9 }, | |
| 1829 | + | |
| 1830 | +/* These Extended FPop (FIFO) instructions are new in the Fujitsu | |
| 1831 | + MB86934, replacing the CPop instructions from v6 and later | |
| 1832 | + processors. */ | |
| 1833 | + | |
| 1834 | +#define EFPOP1_2(name, op, args) { name, F3F(2, 0x36, op), F3F(~2, ~0x36, ~op)|RS1_G0, args, 0, sparclite } | |
| 1835 | +#define EFPOP1_3(name, op, args) { name, F3F(2, 0x36, op), F3F(~2, ~0x36, ~op), args, 0, sparclite } | |
| 1836 | +#define EFPOP2_2(name, op, args) { name, F3F(2, 0x37, op), F3F(~2, ~0x37, ~op)|RD_G0, args, 0, sparclite } | |
| 1837 | + | |
| 1838 | +EFPOP1_2 ("efitod", 0x0c8, "f,H"), | |
| 1839 | +EFPOP1_2 ("efitos", 0x0c4, "f,g"), | |
| 1840 | +EFPOP1_2 ("efdtoi", 0x0d2, "B,g"), | |
| 1841 | +EFPOP1_2 ("efstoi", 0x0d1, "f,g"), | |
| 1842 | +EFPOP1_2 ("efstod", 0x0c9, "f,H"), | |
| 1843 | +EFPOP1_2 ("efdtos", 0x0c6, "B,g"), | |
| 1844 | +EFPOP1_2 ("efmovs", 0x001, "f,g"), | |
| 1845 | +EFPOP1_2 ("efnegs", 0x005, "f,g"), | |
| 1846 | +EFPOP1_2 ("efabss", 0x009, "f,g"), | |
| 1847 | +EFPOP1_2 ("efsqrtd", 0x02a, "B,H"), | |
| 1848 | +EFPOP1_2 ("efsqrts", 0x029, "f,g"), | |
| 1849 | +EFPOP1_3 ("efaddd", 0x042, "v,B,H"), | |
| 1850 | +EFPOP1_3 ("efadds", 0x041, "e,f,g"), | |
| 1851 | +EFPOP1_3 ("efsubd", 0x046, "v,B,H"), | |
| 1852 | +EFPOP1_3 ("efsubs", 0x045, "e,f,g"), | |
| 1853 | +EFPOP1_3 ("efdivd", 0x04e, "v,B,H"), | |
| 1854 | +EFPOP1_3 ("efdivs", 0x04d, "e,f,g"), | |
| 1855 | +EFPOP1_3 ("efmuld", 0x04a, "v,B,H"), | |
| 1856 | +EFPOP1_3 ("efmuls", 0x049, "e,f,g"), | |
| 1857 | +EFPOP1_3 ("efsmuld", 0x069, "e,f,H"), | |
| 1858 | +EFPOP2_2 ("efcmpd", 0x052, "v,B"), | |
| 1859 | +EFPOP2_2 ("efcmped", 0x056, "v,B"), | |
| 1860 | +EFPOP2_2 ("efcmps", 0x051, "e,f"), | |
| 1861 | +EFPOP2_2 ("efcmpes", 0x055, "e,f"), | |
| 1862 | + | |
| 1863 | +#undef EFPOP1_2 | |
| 1864 | +#undef EFPOP1_3 | |
| 1865 | +#undef EFPOP2_2 | |
| 1866 | + | |
| 1867 | +/* These are marked F_ALIAS, so that they won't conflict with sparclite insns | |
| 1868 | + present. Otherwise, the F_ALIAS flag is ignored. */ | |
| 1869 | +{ "cpop1", F3(2, 0x36, 0), F3(~2, ~0x36, ~1), "[1+2],d", F_ALIAS, v6notv9 }, | |
| 1870 | +{ "cpop2", F3(2, 0x37, 0), F3(~2, ~0x37, ~1), "[1+2],d", F_ALIAS, v6notv9 }, | |
| 1871 | + | |
| 1872 | +/* sparclet specific insns */ | |
| 1873 | + | |
| 1874 | +COMMUTEOP ("umac", 0x3e, sparclet), | |
| 1875 | +COMMUTEOP ("smac", 0x3f, sparclet), | |
| 1876 | +COMMUTEOP ("umacd", 0x2e, sparclet), | |
| 1877 | +COMMUTEOP ("smacd", 0x2f, sparclet), | |
| 1878 | +COMMUTEOP ("umuld", 0x09, sparclet), | |
| 1879 | +COMMUTEOP ("smuld", 0x0d, sparclet), | |
| 1880 | + | |
| 1881 | +{ "shuffle", F3(2, 0x2d, 0), F3(~2, ~0x2d, ~0)|ASI(~0), "1,2,d", 0, sparclet }, | |
| 1882 | +{ "shuffle", F3(2, 0x2d, 1), F3(~2, ~0x2d, ~1), "1,i,d", 0, sparclet }, | |
| 1883 | + | |
| 1884 | +/* The manual isn't completely accurate on these insns. The `rs2' field is | |
| 1885 | + treated as being 6 bits to account for 6 bit immediates to cpush. It is | |
| 1886 | + assumed that it is intended that bit 5 is 0 when rs2 contains a reg. */ | |
| 1887 | +#define BIT5 (1<<5) | |
| 1888 | +{ "crdcxt", F3(2, 0x36, 0)|SLCPOP(4), F3(~2, ~0x36, ~0)|SLCPOP(~4)|BIT5|RS2(~0), "U,d", 0, sparclet }, | |
| 1889 | +{ "cwrcxt", F3(2, 0x36, 0)|SLCPOP(3), F3(~2, ~0x36, ~0)|SLCPOP(~3)|BIT5|RS2(~0), "1,u", 0, sparclet }, | |
| 1890 | +{ "cpush", F3(2, 0x36, 0)|SLCPOP(0), F3(~2, ~0x36, ~0)|SLCPOP(~0)|BIT5|RD(~0), "1,2", 0, sparclet }, | |
| 1891 | +{ "cpush", F3(2, 0x36, 1)|SLCPOP(0), F3(~2, ~0x36, ~1)|SLCPOP(~0)|RD(~0), "1,Y", 0, sparclet }, | |
| 1892 | +{ "cpusha", F3(2, 0x36, 0)|SLCPOP(1), F3(~2, ~0x36, ~0)|SLCPOP(~1)|BIT5|RD(~0), "1,2", 0, sparclet }, | |
| 1893 | +{ "cpusha", F3(2, 0x36, 1)|SLCPOP(1), F3(~2, ~0x36, ~1)|SLCPOP(~1)|RD(~0), "1,Y", 0, sparclet }, | |
| 1894 | +{ "cpull", F3(2, 0x36, 0)|SLCPOP(2), F3(~2, ~0x36, ~0)|SLCPOP(~2)|BIT5|RS1(~0)|RS2(~0), "d", 0, sparclet }, | |
| 1895 | +#undef BIT5 | |
| 1896 | + | |
| 1897 | +/* sparclet coprocessor branch insns */ | |
| 1898 | +#define SLCBCC2(opcode, mask, lose) \ | |
| 1899 | + { opcode, (mask), ANNUL|(lose), "l", F_DELAYED|F_CONDBR, sparclet }, \ | |
| 1900 | + { opcode, (mask)|ANNUL, (lose), ",a l", F_DELAYED|F_CONDBR, sparclet } | |
| 1901 | +#define SLCBCC(opcode, mask) \ | |
| 1902 | + SLCBCC2(opcode, F2(0, 7)|COND(mask), F2(~0, ~7)|COND(~(mask))) | |
| 1903 | + | |
| 1904 | +/* cbn,cba can't be defined here because they're defined elsewhere and GAS | |
| 1905 | + requires all mnemonics of the same name to be consecutive. */ | |
| 1906 | +/*SLCBCC("cbn", 0), - already defined */ | |
| 1907 | +SLCBCC("cbe", 1), | |
| 1908 | +SLCBCC("cbf", 2), | |
| 1909 | +SLCBCC("cbef", 3), | |
| 1910 | +SLCBCC("cbr", 4), | |
| 1911 | +SLCBCC("cber", 5), | |
| 1912 | +SLCBCC("cbfr", 6), | |
| 1913 | +SLCBCC("cbefr", 7), | |
| 1914 | +/*SLCBCC("cba", 8), - already defined */ | |
| 1915 | +SLCBCC("cbne", 9), | |
| 1916 | +SLCBCC("cbnf", 10), | |
| 1917 | +SLCBCC("cbnef", 11), | |
| 1918 | +SLCBCC("cbnr", 12), | |
| 1919 | +SLCBCC("cbner", 13), | |
| 1920 | +SLCBCC("cbnfr", 14), | |
| 1921 | +SLCBCC("cbnefr", 15), | |
| 1922 | + | |
| 1923 | +#undef SLCBCC2 | |
| 1924 | +#undef SLCBCC | |
| 1925 | + | |
| 1926 | +{ "casa", F3(3, 0x3c, 0), F3(~3, ~0x3c, ~0), "[1]A,2,d", 0, v9 }, | |
| 1927 | +{ "casa", F3(3, 0x3c, 1), F3(~3, ~0x3c, ~1), "[1]o,2,d", 0, v9 }, | |
| 1928 | +{ "casxa", F3(3, 0x3e, 0), F3(~3, ~0x3e, ~0), "[1]A,2,d", 0, v9 }, | |
| 1929 | +{ "casxa", F3(3, 0x3e, 1), F3(~3, ~0x3e, ~1), "[1]o,2,d", 0, v9 }, | |
| 1930 | + | |
| 1931 | +/* v9 synthetic insns */ | |
| 1932 | +{ "iprefetch", F2(0, 1)|(2<<20)|BPRED, F2(~0, ~1)|(1<<20)|ANNUL|COND(~0), "G", 0, v9 }, /* bn,a,pt %xcc,label */ | |
| 1933 | +{ "signx", F3(2, 0x27, 0), F3(~2, ~0x27, ~0)|(1<<12)|ASI(~0)|RS2_G0, "1,d", F_ALIAS, v9 }, /* sra rs1,%g0,rd */ | |
| 1934 | +{ "signx", F3(2, 0x27, 0), F3(~2, ~0x27, ~0)|(1<<12)|ASI(~0)|RS2_G0, "r", F_ALIAS, v9 }, /* sra rd,%g0,rd */ | |
| 1935 | +{ "clruw", F3(2, 0x26, 0), F3(~2, ~0x26, ~0)|(1<<12)|ASI(~0)|RS2_G0, "1,d", F_ALIAS, v9 }, /* srl rs1,%g0,rd */ | |
| 1936 | +{ "clruw", F3(2, 0x26, 0), F3(~2, ~0x26, ~0)|(1<<12)|ASI(~0)|RS2_G0, "r", F_ALIAS, v9 }, /* srl rd,%g0,rd */ | |
| 1937 | +{ "cas", F3(3, 0x3c, 0)|ASI(0x80), F3(~3, ~0x3c, ~0)|ASI(~0x80), "[1],2,d", F_ALIAS, v9 }, /* casa [rs1]ASI_P,rs2,rd */ | |
| 1938 | +{ "casl", F3(3, 0x3c, 0)|ASI(0x88), F3(~3, ~0x3c, ~0)|ASI(~0x88), "[1],2,d", F_ALIAS, v9 }, /* casa [rs1]ASI_P_L,rs2,rd */ | |
| 1939 | +{ "casx", F3(3, 0x3e, 0)|ASI(0x80), F3(~3, ~0x3e, ~0)|ASI(~0x80), "[1],2,d", F_ALIAS, v9 }, /* casxa [rs1]ASI_P,rs2,rd */ | |
| 1940 | +{ "casxl", F3(3, 0x3e, 0)|ASI(0x88), F3(~3, ~0x3e, ~0)|ASI(~0x88), "[1],2,d", F_ALIAS, v9 }, /* casxa [rs1]ASI_P_L,rs2,rd */ | |
| 1941 | + | |
| 1942 | +/* Ultrasparc extensions */ | |
| 1943 | +{ "shutdown", F3F(2, 0x36, 0x080), F3F(~2, ~0x36, ~0x080)|RD_G0|RS1_G0|RS2_G0, "", 0, v9a }, | |
| 1944 | + | |
| 1945 | +/* FIXME: Do we want to mark these as F_FLOAT, or something similar? */ | |
| 1946 | +{ "fpadd16", F3F(2, 0x36, 0x050), F3F(~2, ~0x36, ~0x050), "v,B,H", 0, v9a }, | |
| 1947 | +{ "fpadd16s", F3F(2, 0x36, 0x051), F3F(~2, ~0x36, ~0x051), "e,f,g", 0, v9a }, | |
| 1948 | +{ "fpadd32", F3F(2, 0x36, 0x052), F3F(~2, ~0x36, ~0x052), "v,B,H", 0, v9a }, | |
| 1949 | +{ "fpadd32s", F3F(2, 0x36, 0x053), F3F(~2, ~0x36, ~0x053), "e,f,g", 0, v9a }, | |
| 1950 | +{ "fpsub16", F3F(2, 0x36, 0x054), F3F(~2, ~0x36, ~0x054), "v,B,H", 0, v9a }, | |
| 1951 | +{ "fpsub16s", F3F(2, 0x36, 0x055), F3F(~2, ~0x36, ~0x055), "e,f,g", 0, v9a }, | |
| 1952 | +{ "fpsub32", F3F(2, 0x36, 0x056), F3F(~2, ~0x36, ~0x056), "v,B,H", 0, v9a }, | |
| 1953 | +{ "fpsub32s", F3F(2, 0x36, 0x057), F3F(~2, ~0x36, ~0x057), "e,f,g", 0, v9a }, | |
| 1954 | + | |
| 1955 | +{ "fpack32", F3F(2, 0x36, 0x03a), F3F(~2, ~0x36, ~0x03a), "v,B,H", 0, v9a }, | |
| 1956 | +{ "fpack16", F3F(2, 0x36, 0x03b), F3F(~2, ~0x36, ~0x03b)|RS1_G0, "B,g", 0, v9a }, | |
| 1957 | +{ "fpackfix", F3F(2, 0x36, 0x03d), F3F(~2, ~0x36, ~0x03d)|RS1_G0, "B,g", 0, v9a }, | |
| 1958 | +{ "fexpand", F3F(2, 0x36, 0x04d), F3F(~2, ~0x36, ~0x04d)|RS1_G0, "f,H", 0, v9a }, | |
| 1959 | +{ "fpmerge", F3F(2, 0x36, 0x04b), F3F(~2, ~0x36, ~0x04b), "e,f,H", 0, v9a }, | |
| 1960 | + | |
| 1961 | +/* Note that the mixing of 32/64 bit regs is intentional. */ | |
| 1962 | +{ "fmul8x16", F3F(2, 0x36, 0x031), F3F(~2, ~0x36, ~0x031), "e,B,H", 0, v9a }, | |
| 1963 | +{ "fmul8x16au", F3F(2, 0x36, 0x033), F3F(~2, ~0x36, ~0x033), "e,f,H", 0, v9a }, | |
| 1964 | +{ "fmul8x16al", F3F(2, 0x36, 0x035), F3F(~2, ~0x36, ~0x035), "e,f,H", 0, v9a }, | |
| 1965 | +{ "fmul8sux16", F3F(2, 0x36, 0x036), F3F(~2, ~0x36, ~0x036), "v,B,H", 0, v9a }, | |
| 1966 | +{ "fmul8ulx16", F3F(2, 0x36, 0x037), F3F(~2, ~0x36, ~0x037), "v,B,H", 0, v9a }, | |
| 1967 | +{ "fmuld8sux16", F3F(2, 0x36, 0x038), F3F(~2, ~0x36, ~0x038), "e,f,H", 0, v9a }, | |
| 1968 | +{ "fmuld8ulx16", F3F(2, 0x36, 0x039), F3F(~2, ~0x36, ~0x039), "e,f,H", 0, v9a }, | |
| 1969 | + | |
| 1970 | +{ "alignaddr", F3F(2, 0x36, 0x018), F3F(~2, ~0x36, ~0x018), "1,2,d", 0, v9a }, | |
| 1971 | +{ "alignaddrl", F3F(2, 0x36, 0x01a), F3F(~2, ~0x36, ~0x01a), "1,2,d", 0, v9a }, | |
| 1972 | +{ "faligndata", F3F(2, 0x36, 0x048), F3F(~2, ~0x36, ~0x048), "v,B,H", 0, v9a }, | |
| 1973 | + | |
| 1974 | +{ "fzero", F3F(2, 0x36, 0x060), F3F(~2, ~0x36, ~0x060), "H", 0, v9a }, | |
| 1975 | +{ "fzeros", F3F(2, 0x36, 0x061), F3F(~2, ~0x36, ~0x061), "g", 0, v9a }, | |
| 1976 | +{ "fone", F3F(2, 0x36, 0x07e), F3F(~2, ~0x36, ~0x07e), "H", 0, v9a }, | |
| 1977 | +{ "fones", F3F(2, 0x36, 0x07f), F3F(~2, ~0x36, ~0x07f), "g", 0, v9a }, | |
| 1978 | +{ "fsrc1", F3F(2, 0x36, 0x074), F3F(~2, ~0x36, ~0x074), "v,H", 0, v9a }, | |
| 1979 | +{ "fsrc1s", F3F(2, 0x36, 0x075), F3F(~2, ~0x36, ~0x075), "e,g", 0, v9a }, | |
| 1980 | +{ "fsrc2", F3F(2, 0x36, 0x078), F3F(~2, ~0x36, ~0x078), "B,H", 0, v9a }, | |
| 1981 | +{ "fsrc2s", F3F(2, 0x36, 0x079), F3F(~2, ~0x36, ~0x079), "f,g", 0, v9a }, | |
| 1982 | +{ "fnot1", F3F(2, 0x36, 0x06a), F3F(~2, ~0x36, ~0x06a), "v,H", 0, v9a }, | |
| 1983 | +{ "fnot1s", F3F(2, 0x36, 0x06b), F3F(~2, ~0x36, ~0x06b), "e,g", 0, v9a }, | |
| 1984 | +{ "fnot2", F3F(2, 0x36, 0x066), F3F(~2, ~0x36, ~0x066), "B,H", 0, v9a }, | |
| 1985 | +{ "fnot2s", F3F(2, 0x36, 0x067), F3F(~2, ~0x36, ~0x067), "f,g", 0, v9a }, | |
| 1986 | +{ "for", F3F(2, 0x36, 0x07c), F3F(~2, ~0x36, ~0x07c), "v,B,H", 0, v9a }, | |
| 1987 | +{ "fors", F3F(2, 0x36, 0x07d), F3F(~2, ~0x36, ~0x07d), "e,f,g", 0, v9a }, | |
| 1988 | +{ "fnor", F3F(2, 0x36, 0x062), F3F(~2, ~0x36, ~0x062), "v,B,H", 0, v9a }, | |
| 1989 | +{ "fnors", F3F(2, 0x36, 0x063), F3F(~2, ~0x36, ~0x063), "e,f,g", 0, v9a }, | |
| 1990 | +{ "fand", F3F(2, 0x36, 0x070), F3F(~2, ~0x36, ~0x070), "v,B,H", 0, v9a }, | |
| 1991 | +{ "fands", F3F(2, 0x36, 0x071), F3F(~2, ~0x36, ~0x071), "e,f,g", 0, v9a }, | |
| 1992 | +{ "fnand", F3F(2, 0x36, 0x06e), F3F(~2, ~0x36, ~0x06e), "v,B,H", 0, v9a }, | |
| 1993 | +{ "fnands", F3F(2, 0x36, 0x06f), F3F(~2, ~0x36, ~0x06f), "e,f,g", 0, v9a }, | |
| 1994 | +{ "fxor", F3F(2, 0x36, 0x06c), F3F(~2, ~0x36, ~0x06c), "v,B,H", 0, v9a }, | |
| 1995 | +{ "fxors", F3F(2, 0x36, 0x06d), F3F(~2, ~0x36, ~0x06d), "e,f,g", 0, v9a }, | |
| 1996 | +{ "fxnor", F3F(2, 0x36, 0x072), F3F(~2, ~0x36, ~0x072), "v,B,H", 0, v9a }, | |
| 1997 | +{ "fxnors", F3F(2, 0x36, 0x073), F3F(~2, ~0x36, ~0x073), "e,f,g", 0, v9a }, | |
| 1998 | +{ "fornot1", F3F(2, 0x36, 0x07a), F3F(~2, ~0x36, ~0x07a), "v,B,H", 0, v9a }, | |
| 1999 | +{ "fornot1s", F3F(2, 0x36, 0x07b), F3F(~2, ~0x36, ~0x07b), "e,f,g", 0, v9a }, | |
| 2000 | +{ "fornot2", F3F(2, 0x36, 0x076), F3F(~2, ~0x36, ~0x076), "v,B,H", 0, v9a }, | |
| 2001 | +{ "fornot2s", F3F(2, 0x36, 0x077), F3F(~2, ~0x36, ~0x077), "e,f,g", 0, v9a }, | |
| 2002 | +{ "fandnot1", F3F(2, 0x36, 0x068), F3F(~2, ~0x36, ~0x068), "v,B,H", 0, v9a }, | |
| 2003 | +{ "fandnot1s", F3F(2, 0x36, 0x069), F3F(~2, ~0x36, ~0x069), "e,f,g", 0, v9a }, | |
| 2004 | +{ "fandnot2", F3F(2, 0x36, 0x064), F3F(~2, ~0x36, ~0x064), "v,B,H", 0, v9a }, | |
| 2005 | +{ "fandnot2s", F3F(2, 0x36, 0x065), F3F(~2, ~0x36, ~0x065), "e,f,g", 0, v9a }, | |
| 2006 | + | |
| 2007 | +{ "fcmpgt16", F3F(2, 0x36, 0x028), F3F(~2, ~0x36, ~0x028), "v,B,d", 0, v9a }, | |
| 2008 | +{ "fcmpgt32", F3F(2, 0x36, 0x02c), F3F(~2, ~0x36, ~0x02c), "v,B,d", 0, v9a }, | |
| 2009 | +{ "fcmple16", F3F(2, 0x36, 0x020), F3F(~2, ~0x36, ~0x020), "v,B,d", 0, v9a }, | |
| 2010 | +{ "fcmple32", F3F(2, 0x36, 0x024), F3F(~2, ~0x36, ~0x024), "v,B,d", 0, v9a }, | |
| 2011 | +{ "fcmpne16", F3F(2, 0x36, 0x022), F3F(~2, ~0x36, ~0x022), "v,B,d", 0, v9a }, | |
| 2012 | +{ "fcmpne32", F3F(2, 0x36, 0x026), F3F(~2, ~0x36, ~0x026), "v,B,d", 0, v9a }, | |
| 2013 | +{ "fcmpeq16", F3F(2, 0x36, 0x02a), F3F(~2, ~0x36, ~0x02a), "v,B,d", 0, v9a }, | |
| 2014 | +{ "fcmpeq32", F3F(2, 0x36, 0x02e), F3F(~2, ~0x36, ~0x02e), "v,B,d", 0, v9a }, | |
| 2015 | + | |
| 2016 | +{ "edge8", F3F(2, 0x36, 0x000), F3F(~2, ~0x36, ~0x000), "1,2,d", 0, v9a }, | |
| 2017 | +{ "edge8l", F3F(2, 0x36, 0x002), F3F(~2, ~0x36, ~0x002), "1,2,d", 0, v9a }, | |
| 2018 | +{ "edge16", F3F(2, 0x36, 0x004), F3F(~2, ~0x36, ~0x004), "1,2,d", 0, v9a }, | |
| 2019 | +{ "edge16l", F3F(2, 0x36, 0x006), F3F(~2, ~0x36, ~0x006), "1,2,d", 0, v9a }, | |
| 2020 | +{ "edge32", F3F(2, 0x36, 0x008), F3F(~2, ~0x36, ~0x008), "1,2,d", 0, v9a }, | |
| 2021 | +{ "edge32l", F3F(2, 0x36, 0x00a), F3F(~2, ~0x36, ~0x00a), "1,2,d", 0, v9a }, | |
| 2022 | + | |
| 2023 | +{ "pdist", F3F(2, 0x36, 0x03e), F3F(~2, ~0x36, ~0x03e), "v,B,H", 0, v9a }, | |
| 2024 | + | |
| 2025 | +{ "array8", F3F(2, 0x36, 0x010), F3F(~2, ~0x36, ~0x010), "1,2,d", 0, v9a }, | |
| 2026 | +{ "array16", F3F(2, 0x36, 0x012), F3F(~2, ~0x36, ~0x012), "1,2,d", 0, v9a }, | |
| 2027 | +{ "array32", F3F(2, 0x36, 0x014), F3F(~2, ~0x36, ~0x014), "1,2,d", 0, v9a }, | |
| 2028 | + | |
| 2029 | +/* Cheetah instructions */ | |
| 2030 | +{ "edge8n", F3F(2, 0x36, 0x001), F3F(~2, ~0x36, ~0x001), "1,2,d", 0, v9b }, | |
| 2031 | +{ "edge8ln", F3F(2, 0x36, 0x003), F3F(~2, ~0x36, ~0x003), "1,2,d", 0, v9b }, | |
| 2032 | +{ "edge16n", F3F(2, 0x36, 0x005), F3F(~2, ~0x36, ~0x005), "1,2,d", 0, v9b }, | |
| 2033 | +{ "edge16ln", F3F(2, 0x36, 0x007), F3F(~2, ~0x36, ~0x007), "1,2,d", 0, v9b }, | |
| 2034 | +{ "edge32n", F3F(2, 0x36, 0x009), F3F(~2, ~0x36, ~0x009), "1,2,d", 0, v9b }, | |
| 2035 | +{ "edge32ln", F3F(2, 0x36, 0x00b), F3F(~2, ~0x36, ~0x00b), "1,2,d", 0, v9b }, | |
| 2036 | + | |
| 2037 | +{ "bmask", F3F(2, 0x36, 0x019), F3F(~2, ~0x36, ~0x019), "1,2,d", 0, v9b }, | |
| 2038 | +{ "bshuffle", F3F(2, 0x36, 0x04c), F3F(~2, ~0x36, ~0x04c), "v,B,H", 0, v9b }, | |
| 2039 | + | |
| 2040 | +{ "siam", F3F(2, 0x36, 0x081), F3F(~2, ~0x36, ~0x081)|RD_G0|RS1_G0|RS2(~7), "3", 0, v9b }, | |
| 2041 | + | |
| 2042 | +/* More v9 specific insns, these need to come last so they do not clash | |
| 2043 | + with v9a instructions such as "edge8" which looks like impdep1. */ | |
| 2044 | + | |
| 2045 | +#define IMPDEP(name, code) \ | |
| 2046 | +{ name, F3(2, code, 0), F3(~2, ~code, ~0)|ASI(~0), "1,2,d", 0, v9notv9a }, \ | |
| 2047 | +{ name, F3(2, code, 1), F3(~2, ~code, ~1), "1,i,d", 0, v9notv9a }, \ | |
| 2048 | +{ name, F3(2, code, 0), F3(~2, ~code, ~0), "x,1,2,d", 0, v9notv9a }, \ | |
| 2049 | +{ name, F3(2, code, 0), F3(~2, ~code, ~0), "x,e,f,g", 0, v9notv9a } | |
| 2050 | + | |
| 2051 | +IMPDEP ("impdep1", 0x36), | |
| 2052 | +IMPDEP ("impdep2", 0x37), | |
| 2053 | + | |
| 2054 | +#undef IMPDEP | |
| 2055 | + | |
| 2056 | +}; | |
| 2057 | + | |
| 2058 | +const int sparc_num_opcodes = ((sizeof sparc_opcodes)/(sizeof sparc_opcodes[0])); | |
| 2059 | + | |
| 2060 | +/* Utilities for argument parsing. */ | |
| 2061 | + | |
| 2062 | +typedef struct | |
| 2063 | +{ | |
| 2064 | + int value; | |
| 2065 | + const char *name; | |
| 2066 | +} arg; | |
| 2067 | + | |
| 2068 | +/* Look up NAME in TABLE. */ | |
| 2069 | + | |
| 2070 | +static int lookup_name PARAMS ((const arg *, const char *)); | |
| 2071 | +static const char *lookup_value PARAMS ((const arg *, int)); | |
| 2072 | + | |
| 2073 | +static int | |
| 2074 | +lookup_name (table, name) | |
| 2075 | + const arg *table; | |
| 2076 | + const char *name; | |
| 2077 | +{ | |
| 2078 | + const arg *p; | |
| 2079 | + | |
| 2080 | + for (p = table; p->name; ++p) | |
| 2081 | + if (strcmp (name, p->name) == 0) | |
| 2082 | + return p->value; | |
| 2083 | + | |
| 2084 | + return -1; | |
| 2085 | +} | |
| 2086 | + | |
| 2087 | +/* Look up VALUE in TABLE. */ | |
| 2088 | + | |
| 2089 | +static const char * | |
| 2090 | +lookup_value (table, value) | |
| 2091 | + const arg *table; | |
| 2092 | + int value; | |
| 2093 | +{ | |
| 2094 | + const arg *p; | |
| 2095 | + | |
| 2096 | + for (p = table; p->name; ++p) | |
| 2097 | + if (value == p->value) | |
| 2098 | + return p->name; | |
| 2099 | + | |
| 2100 | + return (char *) 0; | |
| 2101 | +} | |
| 2102 | + | |
| 2103 | +/* Handle ASI's. */ | |
| 2104 | + | |
| 2105 | +static arg asi_table[] = | |
| 2106 | +{ | |
| 2107 | + /* These are in the v9 architecture manual. */ | |
| 2108 | + /* The shorter versions appear first, they're here because Sun's as has them. | |
| 2109 | + Sun's as uses #ASI_P_L instead of #ASI_PL (which appears in the | |
| 2110 | + UltraSPARC architecture manual). */ | |
| 2111 | + { 0x04, "#ASI_N" }, | |
| 2112 | + { 0x0c, "#ASI_N_L" }, | |
| 2113 | + { 0x10, "#ASI_AIUP" }, | |
| 2114 | + { 0x11, "#ASI_AIUS" }, | |
| 2115 | + { 0x18, "#ASI_AIUP_L" }, | |
| 2116 | + { 0x19, "#ASI_AIUS_L" }, | |
| 2117 | + { 0x80, "#ASI_P" }, | |
| 2118 | + { 0x81, "#ASI_S" }, | |
| 2119 | + { 0x82, "#ASI_PNF" }, | |
| 2120 | + { 0x83, "#ASI_SNF" }, | |
| 2121 | + { 0x88, "#ASI_P_L" }, | |
| 2122 | + { 0x89, "#ASI_S_L" }, | |
| 2123 | + { 0x8a, "#ASI_PNF_L" }, | |
| 2124 | + { 0x8b, "#ASI_SNF_L" }, | |
| 2125 | + { 0x04, "#ASI_NUCLEUS" }, | |
| 2126 | + { 0x0c, "#ASI_NUCLEUS_LITTLE" }, | |
| 2127 | + { 0x10, "#ASI_AS_IF_USER_PRIMARY" }, | |
| 2128 | + { 0x11, "#ASI_AS_IF_USER_SECONDARY" }, | |
| 2129 | + { 0x18, "#ASI_AS_IF_USER_PRIMARY_LITTLE" }, | |
| 2130 | + { 0x19, "#ASI_AS_IF_USER_SECONDARY_LITTLE" }, | |
| 2131 | + { 0x80, "#ASI_PRIMARY" }, | |
| 2132 | + { 0x81, "#ASI_SECONDARY" }, | |
| 2133 | + { 0x82, "#ASI_PRIMARY_NOFAULT" }, | |
| 2134 | + { 0x83, "#ASI_SECONDARY_NOFAULT" }, | |
| 2135 | + { 0x88, "#ASI_PRIMARY_LITTLE" }, | |
| 2136 | + { 0x89, "#ASI_SECONDARY_LITTLE" }, | |
| 2137 | + { 0x8a, "#ASI_PRIMARY_NOFAULT_LITTLE" }, | |
| 2138 | + { 0x8b, "#ASI_SECONDARY_NOFAULT_LITTLE" }, | |
| 2139 | + /* These are UltraSPARC extensions. */ | |
| 2140 | + /* FIXME: There are dozens of them. Not sure we want them all. | |
| 2141 | + Most are for kernel building but some are for vis type stuff. */ | |
| 2142 | + { 0, 0 } | |
| 2143 | +}; | |
| 2144 | + | |
| 2145 | +/* Return the value for ASI NAME, or -1 if not found. */ | |
| 2146 | + | |
| 2147 | +int | |
| 2148 | +sparc_encode_asi (name) | |
| 2149 | + const char *name; | |
| 2150 | +{ | |
| 2151 | + return lookup_name (asi_table, name); | |
| 2152 | +} | |
| 2153 | + | |
| 2154 | +/* Return the name for ASI value VALUE or NULL if not found. */ | |
| 2155 | + | |
| 2156 | +const char * | |
| 2157 | +sparc_decode_asi (value) | |
| 2158 | + int value; | |
| 2159 | +{ | |
| 2160 | + return lookup_value (asi_table, value); | |
| 2161 | +} | |
| 2162 | + | |
| 2163 | +/* Handle membar masks. */ | |
| 2164 | + | |
| 2165 | +static arg membar_table[] = | |
| 2166 | +{ | |
| 2167 | + { 0x40, "#Sync" }, | |
| 2168 | + { 0x20, "#MemIssue" }, | |
| 2169 | + { 0x10, "#Lookaside" }, | |
| 2170 | + { 0x08, "#StoreStore" }, | |
| 2171 | + { 0x04, "#LoadStore" }, | |
| 2172 | + { 0x02, "#StoreLoad" }, | |
| 2173 | + { 0x01, "#LoadLoad" }, | |
| 2174 | + { 0, 0 } | |
| 2175 | +}; | |
| 2176 | + | |
| 2177 | +/* Return the value for membar arg NAME, or -1 if not found. */ | |
| 2178 | + | |
| 2179 | +int | |
| 2180 | +sparc_encode_membar (name) | |
| 2181 | + const char *name; | |
| 2182 | +{ | |
| 2183 | + return lookup_name (membar_table, name); | |
| 2184 | +} | |
| 2185 | + | |
| 2186 | +/* Return the name for membar value VALUE or NULL if not found. */ | |
| 2187 | + | |
| 2188 | +const char * | |
| 2189 | +sparc_decode_membar (value) | |
| 2190 | + int value; | |
| 2191 | +{ | |
| 2192 | + return lookup_value (membar_table, value); | |
| 2193 | +} | |
| 2194 | + | |
| 2195 | +/* Handle prefetch args. */ | |
| 2196 | + | |
| 2197 | +static arg prefetch_table[] = | |
| 2198 | +{ | |
| 2199 | + { 0, "#n_reads" }, | |
| 2200 | + { 1, "#one_read" }, | |
| 2201 | + { 2, "#n_writes" }, | |
| 2202 | + { 3, "#one_write" }, | |
| 2203 | + { 4, "#page" }, | |
| 2204 | + { 16, "#invalidate" }, | |
| 2205 | + { 0, 0 } | |
| 2206 | +}; | |
| 2207 | + | |
| 2208 | +/* Return the value for prefetch arg NAME, or -1 if not found. */ | |
| 2209 | + | |
| 2210 | +int | |
| 2211 | +sparc_encode_prefetch (name) | |
| 2212 | + const char *name; | |
| 2213 | +{ | |
| 2214 | + return lookup_name (prefetch_table, name); | |
| 2215 | +} | |
| 2216 | + | |
| 2217 | +/* Return the name for prefetch value VALUE or NULL if not found. */ | |
| 2218 | + | |
| 2219 | +const char * | |
| 2220 | +sparc_decode_prefetch (value) | |
| 2221 | + int value; | |
| 2222 | +{ | |
| 2223 | + return lookup_value (prefetch_table, value); | |
| 2224 | +} | |
| 2225 | + | |
| 2226 | +/* Handle sparclet coprocessor registers. */ | |
| 2227 | + | |
| 2228 | +static arg sparclet_cpreg_table[] = | |
| 2229 | +{ | |
| 2230 | + { 0, "%ccsr" }, | |
| 2231 | + { 1, "%ccfr" }, | |
| 2232 | + { 2, "%cccrcr" }, | |
| 2233 | + { 3, "%ccpr" }, | |
| 2234 | + { 4, "%ccsr2" }, | |
| 2235 | + { 5, "%cccrr" }, | |
| 2236 | + { 6, "%ccrstr" }, | |
| 2237 | + { 0, 0 } | |
| 2238 | +}; | |
| 2239 | + | |
| 2240 | +/* Return the value for sparclet cpreg arg NAME, or -1 if not found. */ | |
| 2241 | + | |
| 2242 | +int | |
| 2243 | +sparc_encode_sparclet_cpreg (name) | |
| 2244 | + const char *name; | |
| 2245 | +{ | |
| 2246 | + return lookup_name (sparclet_cpreg_table, name); | |
| 2247 | +} | |
| 2248 | + | |
| 2249 | +/* Return the name for sparclet cpreg value VALUE or NULL if not found. */ | |
| 2250 | + | |
| 2251 | +const char * | |
| 2252 | +sparc_decode_sparclet_cpreg (value) | |
| 2253 | + int value; | |
| 2254 | +{ | |
| 2255 | + return lookup_value (sparclet_cpreg_table, value); | |
| 2256 | +} | |
| 2257 | + | |
| 2258 | +#undef MASK_V9 | |
| 2259 | + | |
| 2260 | +/* Bitmask of v9 architectures. */ | |
| 2261 | +#define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \ | |
| 2262 | + | (1 << SPARC_OPCODE_ARCH_V9A) \ | |
| 2263 | + | (1 << SPARC_OPCODE_ARCH_V9B)) | |
| 2264 | +/* 1 if INSN is for v9 only. */ | |
| 2265 | +#define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9)) | |
| 2266 | +/* 1 if INSN is for v9. */ | |
| 2267 | +#define V9_P(insn) (((insn)->architecture & MASK_V9) != 0) | |
| 2268 | + | |
| 2269 | +/* The sorted opcode table. */ | |
| 2270 | +static const struct sparc_opcode **sorted_opcodes; | |
| 2271 | + | |
| 2272 | +/* For faster lookup, after insns are sorted they are hashed. */ | |
| 2273 | +/* ??? I think there is room for even more improvement. */ | |
| 2274 | + | |
| 2275 | +#define HASH_SIZE 256 | |
| 2276 | +/* It is important that we only look at insn code bits as that is how the | |
| 2277 | + opcode table is hashed. OPCODE_BITS is a table of valid bits for each | |
| 2278 | + of the main types (0,1,2,3). */ | |
| 2279 | +static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 }; | |
| 2280 | +#define HASH_INSN(INSN) \ | |
| 2281 | + ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19)) | |
| 2282 | +struct opcode_hash { | |
| 2283 | + struct opcode_hash *next; | |
| 2284 | + const struct sparc_opcode *opcode; | |
| 2285 | +}; | |
| 2286 | +static struct opcode_hash *opcode_hash_table[HASH_SIZE]; | |
| 2287 | + | |
| 2288 | +static void build_hash_table | |
| 2289 | + PARAMS ((const struct sparc_opcode **, struct opcode_hash **, int)); | |
| 2290 | +static int is_delayed_branch PARAMS ((unsigned long)); | |
| 2291 | +static int compare_opcodes PARAMS ((const void *, const void *)); | |
| 2292 | +static int compute_arch_mask PARAMS ((unsigned long)); | |
| 2293 | + | |
| 2294 | +/* Sign-extend a value which is N bits long. */ | |
| 2295 | +#define SEX(value, bits) \ | |
| 2296 | + ((((int)(value)) << ((8 * sizeof (int)) - bits)) \ | |
| 2297 | + >> ((8 * sizeof (int)) - bits) ) | |
| 2298 | + | |
| 2299 | +static char *reg_names[] = | |
| 2300 | +{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", | |
| 2301 | + "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", | |
| 2302 | + "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", | |
| 2303 | + "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", | |
| 2304 | + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", | |
| 2305 | + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", | |
| 2306 | + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", | |
| 2307 | + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", | |
| 2308 | + "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39", | |
| 2309 | + "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47", | |
| 2310 | + "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55", | |
| 2311 | + "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63", | |
| 2312 | +/* psr, wim, tbr, fpsr, cpsr are v8 only. */ | |
| 2313 | + "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" | |
| 2314 | +}; | |
| 2315 | + | |
| 2316 | +#define freg_names (®_names[4 * 8]) | |
| 2317 | + | |
| 2318 | +/* These are ordered according to there register number in | |
| 2319 | + rdpr and wrpr insns. */ | |
| 2320 | +static char *v9_priv_reg_names[] = | |
| 2321 | +{ | |
| 2322 | + "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl", | |
| 2323 | + "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin", | |
| 2324 | + "wstate", "fq" | |
| 2325 | + /* "ver" - special cased */ | |
| 2326 | +}; | |
| 2327 | + | |
| 2328 | +/* These are ordered according to there register number in | |
| 2329 | + rd and wr insns (-16). */ | |
| 2330 | +static char *v9a_asr_reg_names[] = | |
| 2331 | +{ | |
| 2332 | + "pcr", "pic", "dcr", "gsr", "set_softint", "clear_softint", | |
| 2333 | + "softint", "tick_cmpr", "sys_tick", "sys_tick_cmpr" | |
| 2334 | +}; | |
| 2335 | + | |
| 2336 | +/* Macros used to extract instruction fields. Not all fields have | |
| 2337 | + macros defined here, only those which are actually used. */ | |
| 2338 | + | |
| 2339 | +#define X_RD(i) (((i) >> 25) & 0x1f) | |
| 2340 | +#define X_RS1(i) (((i) >> 14) & 0x1f) | |
| 2341 | +#define X_LDST_I(i) (((i) >> 13) & 1) | |
| 2342 | +#define X_ASI(i) (((i) >> 5) & 0xff) | |
| 2343 | +#define X_RS2(i) (((i) >> 0) & 0x1f) | |
| 2344 | +#define X_IMM(i,n) (((i) >> 0) & ((1 << (n)) - 1)) | |
| 2345 | +#define X_SIMM(i,n) SEX (X_IMM ((i), (n)), (n)) | |
| 2346 | +#define X_DISP22(i) (((i) >> 0) & 0x3fffff) | |
| 2347 | +#define X_IMM22(i) X_DISP22 (i) | |
| 2348 | +#define X_DISP30(i) (((i) >> 0) & 0x3fffffff) | |
| 2349 | + | |
| 2350 | +/* These are for v9. */ | |
| 2351 | +#define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff)) | |
| 2352 | +#define X_DISP19(i) (((i) >> 0) & 0x7ffff) | |
| 2353 | +#define X_MEMBAR(i) ((i) & 0x7f) | |
| 2354 | + | |
| 2355 | +/* Here is the union which was used to extract instruction fields | |
| 2356 | + before the shift and mask macros were written. | |
| 2357 | + | |
| 2358 | + union sparc_insn | |
| 2359 | + { | |
| 2360 | + unsigned long int code; | |
| 2361 | + struct | |
| 2362 | + { | |
| 2363 | + unsigned int anop:2; | |
| 2364 | + #define op ldst.anop | |
| 2365 | + unsigned int anrd:5; | |
| 2366 | + #define rd ldst.anrd | |
| 2367 | + unsigned int op3:6; | |
| 2368 | + unsigned int anrs1:5; | |
| 2369 | + #define rs1 ldst.anrs1 | |
| 2370 | + unsigned int i:1; | |
| 2371 | + unsigned int anasi:8; | |
| 2372 | + #define asi ldst.anasi | |
| 2373 | + unsigned int anrs2:5; | |
| 2374 | + #define rs2 ldst.anrs2 | |
| 2375 | + #define shcnt rs2 | |
| 2376 | + } ldst; | |
| 2377 | + struct | |
| 2378 | + { | |
| 2379 | + unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1; | |
| 2380 | + unsigned int IMM13:13; | |
| 2381 | + #define imm13 IMM13.IMM13 | |
| 2382 | + } IMM13; | |
| 2383 | + struct | |
| 2384 | + { | |
| 2385 | + unsigned int anop:2; | |
| 2386 | + unsigned int a:1; | |
| 2387 | + unsigned int cond:4; | |
| 2388 | + unsigned int op2:3; | |
| 2389 | + unsigned int DISP22:22; | |
| 2390 | + #define disp22 branch.DISP22 | |
| 2391 | + #define imm22 disp22 | |
| 2392 | + } branch; | |
| 2393 | + struct | |
| 2394 | + { | |
| 2395 | + unsigned int anop:2; | |
| 2396 | + unsigned int a:1; | |
| 2397 | + unsigned int z:1; | |
| 2398 | + unsigned int rcond:3; | |
| 2399 | + unsigned int op2:3; | |
| 2400 | + unsigned int DISP16HI:2; | |
| 2401 | + unsigned int p:1; | |
| 2402 | + unsigned int _rs1:5; | |
| 2403 | + unsigned int DISP16LO:14; | |
| 2404 | + } branch16; | |
| 2405 | + struct | |
| 2406 | + { | |
| 2407 | + unsigned int anop:2; | |
| 2408 | + unsigned int adisp30:30; | |
| 2409 | + #define disp30 call.adisp30 | |
| 2410 | + } call; | |
| 2411 | + }; | |
| 2412 | + | |
| 2413 | + */ | |
| 2414 | + | |
| 2415 | +/* Nonzero if INSN is the opcode for a delayed branch. */ | |
| 2416 | +static int | |
| 2417 | +is_delayed_branch (insn) | |
| 2418 | + unsigned long insn; | |
| 2419 | +{ | |
| 2420 | + struct opcode_hash *op; | |
| 2421 | + | |
| 2422 | + for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next) | |
| 2423 | + { | |
| 2424 | + const struct sparc_opcode *opcode = op->opcode; | |
| 2425 | + if ((opcode->match & insn) == opcode->match | |
| 2426 | + && (opcode->lose & insn) == 0) | |
| 2427 | + return (opcode->flags & F_DELAYED); | |
| 2428 | + } | |
| 2429 | + return 0; | |
| 2430 | +} | |
| 2431 | + | |
| 2432 | +/* extern void qsort (); */ | |
| 2433 | + | |
| 2434 | +/* Records current mask of SPARC_OPCODE_ARCH_FOO values, used to pass value | |
| 2435 | + to compare_opcodes. */ | |
| 2436 | +static unsigned int current_arch_mask; | |
| 2437 | + | |
| 2438 | +/* Print one instruction from MEMADDR on INFO->STREAM. | |
| 2439 | + | |
| 2440 | + We suffix the instruction with a comment that gives the absolute | |
| 2441 | + address involved, as well as its symbolic form, if the instruction | |
| 2442 | + is preceded by a findable `sethi' and it either adds an immediate | |
| 2443 | + displacement to that register, or it is an `add' or `or' instruction | |
| 2444 | + on that register. */ | |
| 2445 | + | |
| 2446 | +int | |
| 2447 | +print_insn_sparc (memaddr, info) | |
| 2448 | + bfd_vma memaddr; | |
| 2449 | + disassemble_info *info; | |
| 2450 | +{ | |
| 2451 | + FILE *stream = info->stream; | |
| 2452 | + bfd_byte buffer[4]; | |
| 2453 | + unsigned long insn; | |
| 2454 | + register struct opcode_hash *op; | |
| 2455 | + /* Nonzero of opcode table has been initialized. */ | |
| 2456 | + static int opcodes_initialized = 0; | |
| 2457 | + /* bfd mach number of last call. */ | |
| 2458 | + static unsigned long current_mach = 0; | |
| 2459 | + bfd_vma (*getword) PARAMS ((const unsigned char *)); | |
| 2460 | + | |
| 2461 | + if (!opcodes_initialized | |
| 2462 | + || info->mach != current_mach) | |
| 2463 | + { | |
| 2464 | + int i; | |
| 2465 | + | |
| 2466 | + current_arch_mask = compute_arch_mask (info->mach); | |
| 2467 | + | |
| 2468 | + if (!opcodes_initialized) | |
| 2469 | + sorted_opcodes = (const struct sparc_opcode **) | |
| 2470 | + malloc (sparc_num_opcodes * sizeof (struct sparc_opcode *)); | |
| 2471 | + /* Reset the sorted table so we can resort it. */ | |
| 2472 | + for (i = 0; i < sparc_num_opcodes; ++i) | |
| 2473 | + sorted_opcodes[i] = &sparc_opcodes[i]; | |
| 2474 | + qsort ((char *) sorted_opcodes, sparc_num_opcodes, | |
| 2475 | + sizeof (sorted_opcodes[0]), compare_opcodes); | |
| 2476 | + | |
| 2477 | + build_hash_table (sorted_opcodes, opcode_hash_table, sparc_num_opcodes); | |
| 2478 | + current_mach = info->mach; | |
| 2479 | + opcodes_initialized = 1; | |
| 2480 | + } | |
| 2481 | + | |
| 2482 | + { | |
| 2483 | + int status = | |
| 2484 | + (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info); | |
| 2485 | + if (status != 0) | |
| 2486 | + { | |
| 2487 | + (*info->memory_error_func) (status, memaddr, info); | |
| 2488 | + return -1; | |
| 2489 | + } | |
| 2490 | + } | |
| 2491 | + | |
| 2492 | + /* On SPARClite variants such as DANlite (sparc86x), instructions | |
| 2493 | + are always big-endian even when the machine is in little-endian mode. */ | |
| 2494 | + if (info->endian == BFD_ENDIAN_BIG || info->mach == bfd_mach_sparc_sparclite) | |
| 2495 | + getword = bfd_getb32; | |
| 2496 | + else | |
| 2497 | + getword = bfd_getl32; | |
| 2498 | + | |
| 2499 | + insn = getword (buffer); | |
| 2500 | + | |
| 2501 | + info->insn_info_valid = 1; /* We do return this info */ | |
| 2502 | + info->insn_type = dis_nonbranch; /* Assume non branch insn */ | |
| 2503 | + info->branch_delay_insns = 0; /* Assume no delay */ | |
| 2504 | + info->target = 0; /* Assume no target known */ | |
| 2505 | + | |
| 2506 | + for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next) | |
| 2507 | + { | |
| 2508 | + const struct sparc_opcode *opcode = op->opcode; | |
| 2509 | + | |
| 2510 | + /* If the insn isn't supported by the current architecture, skip it. */ | |
| 2511 | + if (! (opcode->architecture & current_arch_mask)) | |
| 2512 | + continue; | |
| 2513 | + | |
| 2514 | + if ((opcode->match & insn) == opcode->match | |
| 2515 | + && (opcode->lose & insn) == 0) | |
| 2516 | + { | |
| 2517 | + /* Nonzero means that we have found an instruction which has | |
| 2518 | + the effect of adding or or'ing the imm13 field to rs1. */ | |
| 2519 | + int imm_added_to_rs1 = 0; | |
| 2520 | + int imm_ored_to_rs1 = 0; | |
| 2521 | + | |
| 2522 | + /* Nonzero means that we have found a plus sign in the args | |
| 2523 | + field of the opcode table. */ | |
| 2524 | + int found_plus = 0; | |
| 2525 | + | |
| 2526 | + /* Nonzero means we have an annulled branch. */ | |
| 2527 | + int is_annulled = 0; | |
| 2528 | + | |
| 2529 | + /* Do we have an `add' or `or' instruction combining an | |
| 2530 | + immediate with rs1? */ | |
| 2531 | + if (opcode->match == 0x80102000) /* or */ | |
| 2532 | + imm_ored_to_rs1 = 1; | |
| 2533 | + if (opcode->match == 0x80002000) /* add */ | |
| 2534 | + imm_added_to_rs1 = 1; | |
| 2535 | + | |
| 2536 | + if (X_RS1 (insn) != X_RD (insn) | |
| 2537 | + && strchr (opcode->args, 'r') != 0) | |
| 2538 | + /* Can't do simple format if source and dest are different. */ | |
| 2539 | + continue; | |
| 2540 | + if (X_RS2 (insn) != X_RD (insn) | |
| 2541 | + && strchr (opcode->args, 'O') != 0) | |
| 2542 | + /* Can't do simple format if source and dest are different. */ | |
| 2543 | + continue; | |
| 2544 | + | |
| 2545 | + (*info->fprintf_func) (stream, opcode->name); | |
| 2546 | + | |
| 2547 | + { | |
| 2548 | + register const char *s; | |
| 2549 | + | |
| 2550 | + if (opcode->args[0] != ',') | |
| 2551 | + (*info->fprintf_func) (stream, " "); | |
| 2552 | + for (s = opcode->args; *s != '\0'; ++s) | |
| 2553 | + { | |
| 2554 | + while (*s == ',') | |
| 2555 | + { | |
| 2556 | + (*info->fprintf_func) (stream, ","); | |
| 2557 | + ++s; | |
| 2558 | + switch (*s) { | |
| 2559 | + case 'a': | |
| 2560 | + (*info->fprintf_func) (stream, "a"); | |
| 2561 | + is_annulled = 1; | |
| 2562 | + ++s; | |
| 2563 | + continue; | |
| 2564 | + case 'N': | |
| 2565 | + (*info->fprintf_func) (stream, "pn"); | |
| 2566 | + ++s; | |
| 2567 | + continue; | |
| 2568 | + | |
| 2569 | + case 'T': | |
| 2570 | + (*info->fprintf_func) (stream, "pt"); | |
| 2571 | + ++s; | |
| 2572 | + continue; | |
| 2573 | + | |
| 2574 | + default: | |
| 2575 | + break; | |
| 2576 | + } /* switch on arg */ | |
| 2577 | + } /* while there are comma started args */ | |
| 2578 | + | |
| 2579 | + (*info->fprintf_func) (stream, " "); | |
| 2580 | + | |
| 2581 | + switch (*s) | |
| 2582 | + { | |
| 2583 | + case '+': | |
| 2584 | + found_plus = 1; | |
| 2585 | + | |
| 2586 | + /* note fall-through */ | |
| 2587 | + default: | |
| 2588 | + (*info->fprintf_func) (stream, "%c", *s); | |
| 2589 | + break; | |
| 2590 | + | |
| 2591 | + case '#': | |
| 2592 | + (*info->fprintf_func) (stream, "0"); | |
| 2593 | + break; | |
| 2594 | + | |
| 2595 | +#define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n]) | |
| 2596 | + case '1': | |
| 2597 | + case 'r': | |
| 2598 | + reg (X_RS1 (insn)); | |
| 2599 | + break; | |
| 2600 | + | |
| 2601 | + case '2': | |
| 2602 | + case 'O': | |
| 2603 | + reg (X_RS2 (insn)); | |
| 2604 | + break; | |
| 2605 | + | |
| 2606 | + case 'd': | |
| 2607 | + reg (X_RD (insn)); | |
| 2608 | + break; | |
| 2609 | +#undef reg | |
| 2610 | + | |
| 2611 | +#define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n]) | |
| 2612 | +#define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)]) | |
| 2613 | + case 'e': | |
| 2614 | + freg (X_RS1 (insn)); | |
| 2615 | + break; | |
| 2616 | + case 'v': /* double/even */ | |
| 2617 | + case 'V': /* quad/multiple of 4 */ | |
| 2618 | + fregx (X_RS1 (insn)); | |
| 2619 | + break; | |
| 2620 | + | |
| 2621 | + case 'f': | |
| 2622 | + freg (X_RS2 (insn)); | |
| 2623 | + break; | |
| 2624 | + case 'B': /* double/even */ | |
| 2625 | + case 'R': /* quad/multiple of 4 */ | |
| 2626 | + fregx (X_RS2 (insn)); | |
| 2627 | + break; | |
| 2628 | + | |
| 2629 | + case 'g': | |
| 2630 | + freg (X_RD (insn)); | |
| 2631 | + break; | |
| 2632 | + case 'H': /* double/even */ | |
| 2633 | + case 'J': /* quad/multiple of 4 */ | |
| 2634 | + fregx (X_RD (insn)); | |
| 2635 | + break; | |
| 2636 | +#undef freg | |
| 2637 | +#undef fregx | |
| 2638 | + | |
| 2639 | +#define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n)) | |
| 2640 | + case 'b': | |
| 2641 | + creg (X_RS1 (insn)); | |
| 2642 | + break; | |
| 2643 | + | |
| 2644 | + case 'c': | |
| 2645 | + creg (X_RS2 (insn)); | |
| 2646 | + break; | |
| 2647 | + | |
| 2648 | + case 'D': | |
| 2649 | + creg (X_RD (insn)); | |
| 2650 | + break; | |
| 2651 | +#undef creg | |
| 2652 | + | |
| 2653 | + case 'h': | |
| 2654 | + (*info->fprintf_func) (stream, "%%hi(%#x)", | |
| 2655 | + ((unsigned) 0xFFFFFFFF | |
| 2656 | + & ((int) X_IMM22 (insn) << 10))); | |
| 2657 | + break; | |
| 2658 | + | |
| 2659 | + case 'i': /* 13 bit immediate */ | |
| 2660 | + case 'I': /* 11 bit immediate */ | |
| 2661 | + case 'j': /* 10 bit immediate */ | |
| 2662 | + { | |
| 2663 | + int imm; | |
| 2664 | + | |
| 2665 | + if (*s == 'i') | |
| 2666 | + imm = X_SIMM (insn, 13); | |
| 2667 | + else if (*s == 'I') | |
| 2668 | + imm = X_SIMM (insn, 11); | |
| 2669 | + else | |
| 2670 | + imm = X_SIMM (insn, 10); | |
| 2671 | + | |
| 2672 | + /* Check to see whether we have a 1+i, and take | |
| 2673 | + note of that fact. | |
| 2674 | + | |
| 2675 | + Note: because of the way we sort the table, | |
| 2676 | + we will be matching 1+i rather than i+1, | |
| 2677 | + so it is OK to assume that i is after +, | |
| 2678 | + not before it. */ | |
| 2679 | + if (found_plus) | |
| 2680 | + imm_added_to_rs1 = 1; | |
| 2681 | + | |
| 2682 | + if (imm <= 9) | |
| 2683 | + (*info->fprintf_func) (stream, "%d", imm); | |
| 2684 | + else | |
| 2685 | + (*info->fprintf_func) (stream, "%#x", imm); | |
| 2686 | + } | |
| 2687 | + break; | |
| 2688 | + | |
| 2689 | + case 'X': /* 5 bit unsigned immediate */ | |
| 2690 | + case 'Y': /* 6 bit unsigned immediate */ | |
| 2691 | + { | |
| 2692 | + int imm = X_IMM (insn, *s == 'X' ? 5 : 6); | |
| 2693 | + | |
| 2694 | + if (imm <= 9) | |
| 2695 | + (info->fprintf_func) (stream, "%d", imm); | |
| 2696 | + else | |
| 2697 | + (info->fprintf_func) (stream, "%#x", (unsigned) imm); | |
| 2698 | + } | |
| 2699 | + break; | |
| 2700 | + | |
| 2701 | + case '3': | |
| 2702 | + (info->fprintf_func) (stream, "%d", X_IMM (insn, 3)); | |
| 2703 | + break; | |
| 2704 | + | |
| 2705 | + case 'K': | |
| 2706 | + { | |
| 2707 | + int mask = X_MEMBAR (insn); | |
| 2708 | + int bit = 0x40, printed_one = 0; | |
| 2709 | + const char *name; | |
| 2710 | + | |
| 2711 | + if (mask == 0) | |
| 2712 | + (info->fprintf_func) (stream, "0"); | |
| 2713 | + else | |
| 2714 | + while (bit) | |
| 2715 | + { | |
| 2716 | + if (mask & bit) | |
| 2717 | + { | |
| 2718 | + if (printed_one) | |
| 2719 | + (info->fprintf_func) (stream, "|"); | |
| 2720 | + name = sparc_decode_membar (bit); | |
| 2721 | + (info->fprintf_func) (stream, "%s", name); | |
| 2722 | + printed_one = 1; | |
| 2723 | + } | |
| 2724 | + bit >>= 1; | |
| 2725 | + } | |
| 2726 | + break; | |
| 2727 | + } | |
| 2728 | + | |
| 2729 | + case 'k': | |
| 2730 | + info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4; | |
| 2731 | + (*info->print_address_func) (info->target, info); | |
| 2732 | + break; | |
| 2733 | + | |
| 2734 | + case 'G': | |
| 2735 | + info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4; | |
| 2736 | + (*info->print_address_func) (info->target, info); | |
| 2737 | + break; | |
| 2738 | + | |
| 2739 | + case '6': | |
| 2740 | + case '7': | |
| 2741 | + case '8': | |
| 2742 | + case '9': | |
| 2743 | + (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0'); | |
| 2744 | + break; | |
| 2745 | + | |
| 2746 | + case 'z': | |
| 2747 | + (*info->fprintf_func) (stream, "%%icc"); | |
| 2748 | + break; | |
| 2749 | + | |
| 2750 | + case 'Z': | |
| 2751 | + (*info->fprintf_func) (stream, "%%xcc"); | |
| 2752 | + break; | |
| 2753 | + | |
| 2754 | + case 'E': | |
| 2755 | + (*info->fprintf_func) (stream, "%%ccr"); | |
| 2756 | + break; | |
| 2757 | + | |
| 2758 | + case 's': | |
| 2759 | + (*info->fprintf_func) (stream, "%%fprs"); | |
| 2760 | + break; | |
| 2761 | + | |
| 2762 | + case 'o': | |
| 2763 | + (*info->fprintf_func) (stream, "%%asi"); | |
| 2764 | + break; | |
| 2765 | + | |
| 2766 | + case 'W': | |
| 2767 | + (*info->fprintf_func) (stream, "%%tick"); | |
| 2768 | + break; | |
| 2769 | + | |
| 2770 | + case 'P': | |
| 2771 | + (*info->fprintf_func) (stream, "%%pc"); | |
| 2772 | + break; | |
| 2773 | + | |
| 2774 | + case '?': | |
| 2775 | + if (X_RS1 (insn) == 31) | |
| 2776 | + (*info->fprintf_func) (stream, "%%ver"); | |
| 2777 | + else if ((unsigned) X_RS1 (insn) < 16) | |
| 2778 | + (*info->fprintf_func) (stream, "%%%s", | |
| 2779 | + v9_priv_reg_names[X_RS1 (insn)]); | |
| 2780 | + else | |
| 2781 | + (*info->fprintf_func) (stream, "%%reserved"); | |
| 2782 | + break; | |
| 2783 | + | |
| 2784 | + case '!': | |
| 2785 | + if ((unsigned) X_RD (insn) < 15) | |
| 2786 | + (*info->fprintf_func) (stream, "%%%s", | |
| 2787 | + v9_priv_reg_names[X_RD (insn)]); | |
| 2788 | + else | |
| 2789 | + (*info->fprintf_func) (stream, "%%reserved"); | |
| 2790 | + break; | |
| 2791 | + | |
| 2792 | + case '/': | |
| 2793 | + if (X_RS1 (insn) < 16 || X_RS1 (insn) > 25) | |
| 2794 | + (*info->fprintf_func) (stream, "%%reserved"); | |
| 2795 | + else | |
| 2796 | + (*info->fprintf_func) (stream, "%%%s", | |
| 2797 | + v9a_asr_reg_names[X_RS1 (insn)-16]); | |
| 2798 | + break; | |
| 2799 | + | |
| 2800 | + case '_': | |
| 2801 | + if (X_RD (insn) < 16 || X_RD (insn) > 25) | |
| 2802 | + (*info->fprintf_func) (stream, "%%reserved"); | |
| 2803 | + else | |
| 2804 | + (*info->fprintf_func) (stream, "%%%s", | |
| 2805 | + v9a_asr_reg_names[X_RD (insn)-16]); | |
| 2806 | + break; | |
| 2807 | + | |
| 2808 | + case '*': | |
| 2809 | + { | |
| 2810 | + const char *name = sparc_decode_prefetch (X_RD (insn)); | |
| 2811 | + | |
| 2812 | + if (name) | |
| 2813 | + (*info->fprintf_func) (stream, "%s", name); | |
| 2814 | + else | |
| 2815 | + (*info->fprintf_func) (stream, "%d", X_RD (insn)); | |
| 2816 | + break; | |
| 2817 | + } | |
| 2818 | + | |
| 2819 | + case 'M': | |
| 2820 | + (*info->fprintf_func) (stream, "%%asr%d", X_RS1 (insn)); | |
| 2821 | + break; | |
| 2822 | + | |
| 2823 | + case 'm': | |
| 2824 | + (*info->fprintf_func) (stream, "%%asr%d", X_RD (insn)); | |
| 2825 | + break; | |
| 2826 | + | |
| 2827 | + case 'L': | |
| 2828 | + info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4; | |
| 2829 | + (*info->print_address_func) (info->target, info); | |
| 2830 | + break; | |
| 2831 | + | |
| 2832 | + case 'n': | |
| 2833 | + (*info->fprintf_func) | |
| 2834 | + (stream, "%#x", SEX (X_DISP22 (insn), 22)); | |
| 2835 | + break; | |
| 2836 | + | |
| 2837 | + case 'l': | |
| 2838 | + info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4; | |
| 2839 | + (*info->print_address_func) (info->target, info); | |
| 2840 | + break; | |
| 2841 | + | |
| 2842 | + case 'A': | |
| 2843 | + { | |
| 2844 | + const char *name = sparc_decode_asi (X_ASI (insn)); | |
| 2845 | + | |
| 2846 | + if (name) | |
| 2847 | + (*info->fprintf_func) (stream, "%s", name); | |
| 2848 | + else | |
| 2849 | + (*info->fprintf_func) (stream, "(%d)", X_ASI (insn)); | |
| 2850 | + break; | |
| 2851 | + } | |
| 2852 | + | |
| 2853 | + case 'C': | |
| 2854 | + (*info->fprintf_func) (stream, "%%csr"); | |
| 2855 | + break; | |
| 2856 | + | |
| 2857 | + case 'F': | |
| 2858 | + (*info->fprintf_func) (stream, "%%fsr"); | |
| 2859 | + break; | |
| 2860 | + | |
| 2861 | + case 'p': | |
| 2862 | + (*info->fprintf_func) (stream, "%%psr"); | |
| 2863 | + break; | |
| 2864 | + | |
| 2865 | + case 'q': | |
| 2866 | + (*info->fprintf_func) (stream, "%%fq"); | |
| 2867 | + break; | |
| 2868 | + | |
| 2869 | + case 'Q': | |
| 2870 | + (*info->fprintf_func) (stream, "%%cq"); | |
| 2871 | + break; | |
| 2872 | + | |
| 2873 | + case 't': | |
| 2874 | + (*info->fprintf_func) (stream, "%%tbr"); | |
| 2875 | + break; | |
| 2876 | + | |
| 2877 | + case 'w': | |
| 2878 | + (*info->fprintf_func) (stream, "%%wim"); | |
| 2879 | + break; | |
| 2880 | + | |
| 2881 | + case 'x': | |
| 2882 | + (*info->fprintf_func) (stream, "%d", | |
| 2883 | + ((X_LDST_I (insn) << 8) | |
| 2884 | + + X_ASI (insn))); | |
| 2885 | + break; | |
| 2886 | + | |
| 2887 | + case 'y': | |
| 2888 | + (*info->fprintf_func) (stream, "%%y"); | |
| 2889 | + break; | |
| 2890 | + | |
| 2891 | + case 'u': | |
| 2892 | + case 'U': | |
| 2893 | + { | |
| 2894 | + int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn); | |
| 2895 | + const char *name = sparc_decode_sparclet_cpreg (val); | |
| 2896 | + | |
| 2897 | + if (name) | |
| 2898 | + (*info->fprintf_func) (stream, "%s", name); | |
| 2899 | + else | |
| 2900 | + (*info->fprintf_func) (stream, "%%cpreg(%d)", val); | |
| 2901 | + break; | |
| 2902 | + } | |
| 2903 | + } | |
| 2904 | + } | |
| 2905 | + } | |
| 2906 | + | |
| 2907 | + /* If we are adding or or'ing something to rs1, then | |
| 2908 | + check to see whether the previous instruction was | |
| 2909 | + a sethi to the same register as in the sethi. | |
| 2910 | + If so, attempt to print the result of the add or | |
| 2911 | + or (in this context add and or do the same thing) | |
| 2912 | + and its symbolic value. */ | |
| 2913 | + if (imm_ored_to_rs1 || imm_added_to_rs1) | |
| 2914 | + { | |
| 2915 | + unsigned long prev_insn; | |
| 2916 | + int errcode; | |
| 2917 | + | |
| 2918 | + errcode = | |
| 2919 | + (*info->read_memory_func) | |
| 2920 | + (memaddr - 4, buffer, sizeof (buffer), info); | |
| 2921 | + prev_insn = getword (buffer); | |
| 2922 | + | |
| 2923 | + if (errcode == 0) | |
| 2924 | + { | |
| 2925 | + /* If it is a delayed branch, we need to look at the | |
| 2926 | + instruction before the delayed branch. This handles | |
| 2927 | + sequences such as | |
| 2928 | + | |
| 2929 | + sethi %o1, %hi(_foo), %o1 | |
| 2930 | + call _printf | |
| 2931 | + or %o1, %lo(_foo), %o1 | |
| 2932 | + */ | |
| 2933 | + | |
| 2934 | + if (is_delayed_branch (prev_insn)) | |
| 2935 | + { | |
| 2936 | + errcode = (*info->read_memory_func) | |
| 2937 | + (memaddr - 8, buffer, sizeof (buffer), info); | |
| 2938 | + prev_insn = getword (buffer); | |
| 2939 | + } | |
| 2940 | + } | |
| 2941 | + | |
| 2942 | + /* If there was a problem reading memory, then assume | |
| 2943 | + the previous instruction was not sethi. */ | |
| 2944 | + if (errcode == 0) | |
| 2945 | + { | |
| 2946 | + /* Is it sethi to the same register? */ | |
| 2947 | + if ((prev_insn & 0xc1c00000) == 0x01000000 | |
| 2948 | + && X_RD (prev_insn) == X_RS1 (insn)) | |
| 2949 | + { | |
| 2950 | + (*info->fprintf_func) (stream, "\t! "); | |
| 2951 | + info->target = | |
| 2952 | + ((unsigned) 0xFFFFFFFF | |
| 2953 | + & ((int) X_IMM22 (prev_insn) << 10)); | |
| 2954 | + if (imm_added_to_rs1) | |
| 2955 | + info->target += X_SIMM (insn, 13); | |
| 2956 | + else | |
| 2957 | + info->target |= X_SIMM (insn, 13); | |
| 2958 | + (*info->print_address_func) (info->target, info); | |
| 2959 | + info->insn_type = dis_dref; | |
| 2960 | + info->data_size = 4; /* FIXME!!! */ | |
| 2961 | + } | |
| 2962 | + } | |
| 2963 | + } | |
| 2964 | + | |
| 2965 | + if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR)) | |
| 2966 | + { | |
| 2967 | + /* FIXME -- check is_annulled flag */ | |
| 2968 | + if (opcode->flags & F_UNBR) | |
| 2969 | + info->insn_type = dis_branch; | |
| 2970 | + if (opcode->flags & F_CONDBR) | |
| 2971 | + info->insn_type = dis_condbranch; | |
| 2972 | + if (opcode->flags & F_JSR) | |
| 2973 | + info->insn_type = dis_jsr; | |
| 2974 | + if (opcode->flags & F_DELAYED) | |
| 2975 | + info->branch_delay_insns = 1; | |
| 2976 | + } | |
| 2977 | + | |
| 2978 | + return sizeof (buffer); | |
| 2979 | + } | |
| 2980 | + } | |
| 2981 | + | |
| 2982 | + info->insn_type = dis_noninsn; /* Mark as non-valid instruction */ | |
| 2983 | + (*info->fprintf_func) (stream, _("unknown")); | |
| 2984 | + return sizeof (buffer); | |
| 2985 | +} | |
| 2986 | + | |
| 2987 | +/* Given BFD mach number, return a mask of SPARC_OPCODE_ARCH_FOO values. */ | |
| 2988 | + | |
| 2989 | +static int | |
| 2990 | +compute_arch_mask (mach) | |
| 2991 | + unsigned long mach; | |
| 2992 | +{ | |
| 2993 | + switch (mach) | |
| 2994 | + { | |
| 2995 | + case 0 : | |
| 2996 | + case bfd_mach_sparc : | |
| 2997 | + return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8); | |
| 2998 | + case bfd_mach_sparc_sparclet : | |
| 2999 | + return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET); | |
| 3000 | + case bfd_mach_sparc_sparclite : | |
| 3001 | + case bfd_mach_sparc_sparclite_le : | |
| 3002 | + /* sparclites insns are recognized by default (because that's how | |
| 3003 | + they've always been treated, for better or worse). Kludge this by | |
| 3004 | + indicating generic v8 is also selected. */ | |
| 3005 | + return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE) | |
| 3006 | + | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8)); | |
| 3007 | + case bfd_mach_sparc_v8plus : | |
| 3008 | + case bfd_mach_sparc_v9 : | |
| 3009 | + return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9); | |
| 3010 | + case bfd_mach_sparc_v8plusa : | |
| 3011 | + case bfd_mach_sparc_v9a : | |
| 3012 | + return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A); | |
| 3013 | + case bfd_mach_sparc_v8plusb : | |
| 3014 | + case bfd_mach_sparc_v9b : | |
| 3015 | + return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9B); | |
| 3016 | + } | |
| 3017 | + abort (); | |
| 3018 | +} | |
| 3019 | + | |
| 3020 | +/* Compare opcodes A and B. */ | |
| 3021 | + | |
| 3022 | +static int | |
| 3023 | +compare_opcodes (const void *a, const void *b) | |
| 3024 | +{ | |
| 3025 | + struct sparc_opcode *op0 = * (struct sparc_opcode **) a; | |
| 3026 | + struct sparc_opcode *op1 = * (struct sparc_opcode **) b; | |
| 3027 | + unsigned long int match0 = op0->match, match1 = op1->match; | |
| 3028 | + unsigned long int lose0 = op0->lose, lose1 = op1->lose; | |
| 3029 | + register unsigned int i; | |
| 3030 | + | |
| 3031 | + /* If one (and only one) insn isn't supported by the current architecture, | |
| 3032 | + prefer the one that is. If neither are supported, but they're both for | |
| 3033 | + the same architecture, continue processing. Otherwise (both unsupported | |
| 3034 | + and for different architectures), prefer lower numbered arch's (fudged | |
| 3035 | + by comparing the bitmasks). */ | |
| 3036 | + if (op0->architecture & current_arch_mask) | |
| 3037 | + { | |
| 3038 | + if (! (op1->architecture & current_arch_mask)) | |
| 3039 | + return -1; | |
| 3040 | + } | |
| 3041 | + else | |
| 3042 | + { | |
| 3043 | + if (op1->architecture & current_arch_mask) | |
| 3044 | + return 1; | |
| 3045 | + else if (op0->architecture != op1->architecture) | |
| 3046 | + return op0->architecture - op1->architecture; | |
| 3047 | + } | |
| 3048 | + | |
| 3049 | + /* If a bit is set in both match and lose, there is something | |
| 3050 | + wrong with the opcode table. */ | |
| 3051 | + if (match0 & lose0) | |
| 3052 | + { | |
| 3053 | + fprintf | |
| 3054 | + (stderr, | |
| 3055 | + /* xgettext:c-format */ | |
| 3056 | + _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"), | |
| 3057 | + op0->name, match0, lose0); | |
| 3058 | + op0->lose &= ~op0->match; | |
| 3059 | + lose0 = op0->lose; | |
| 3060 | + } | |
| 3061 | + | |
| 3062 | + if (match1 & lose1) | |
| 3063 | + { | |
| 3064 | + fprintf | |
| 3065 | + (stderr, | |
| 3066 | + /* xgettext:c-format */ | |
| 3067 | + _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"), | |
| 3068 | + op1->name, match1, lose1); | |
| 3069 | + op1->lose &= ~op1->match; | |
| 3070 | + lose1 = op1->lose; | |
| 3071 | + } | |
| 3072 | + | |
| 3073 | + /* Because the bits that are variable in one opcode are constant in | |
| 3074 | + another, it is important to order the opcodes in the right order. */ | |
| 3075 | + for (i = 0; i < 32; ++i) | |
| 3076 | + { | |
| 3077 | + unsigned long int x = 1 << i; | |
| 3078 | + int x0 = (match0 & x) != 0; | |
| 3079 | + int x1 = (match1 & x) != 0; | |
| 3080 | + | |
| 3081 | + if (x0 != x1) | |
| 3082 | + return x1 - x0; | |
| 3083 | + } | |
| 3084 | + | |
| 3085 | + for (i = 0; i < 32; ++i) | |
| 3086 | + { | |
| 3087 | + unsigned long int x = 1 << i; | |
| 3088 | + int x0 = (lose0 & x) != 0; | |
| 3089 | + int x1 = (lose1 & x) != 0; | |
| 3090 | + | |
| 3091 | + if (x0 != x1) | |
| 3092 | + return x1 - x0; | |
| 3093 | + } | |
| 3094 | + | |
| 3095 | + /* They are functionally equal. So as long as the opcode table is | |
| 3096 | + valid, we can put whichever one first we want, on aesthetic grounds. */ | |
| 3097 | + | |
| 3098 | + /* Our first aesthetic ground is that aliases defer to real insns. */ | |
| 3099 | + { | |
| 3100 | + int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS); | |
| 3101 | + if (alias_diff != 0) | |
| 3102 | + /* Put the one that isn't an alias first. */ | |
| 3103 | + return alias_diff; | |
| 3104 | + } | |
| 3105 | + | |
| 3106 | + /* Except for aliases, two "identical" instructions had | |
| 3107 | + better have the same opcode. This is a sanity check on the table. */ | |
| 3108 | + i = strcmp (op0->name, op1->name); | |
| 3109 | + if (i) | |
| 3110 | + { | |
| 3111 | + if (op0->flags & F_ALIAS) /* If they're both aliases, be arbitrary. */ | |
| 3112 | + return i; | |
| 3113 | + else | |
| 3114 | + fprintf (stderr, | |
| 3115 | + /* xgettext:c-format */ | |
| 3116 | + _("Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n"), | |
| 3117 | + op0->name, op1->name); | |
| 3118 | + } | |
| 3119 | + | |
| 3120 | + /* Fewer arguments are preferred. */ | |
| 3121 | + { | |
| 3122 | + int length_diff = strlen (op0->args) - strlen (op1->args); | |
| 3123 | + if (length_diff != 0) | |
| 3124 | + /* Put the one with fewer arguments first. */ | |
| 3125 | + return length_diff; | |
| 3126 | + } | |
| 3127 | + | |
| 3128 | + /* Put 1+i before i+1. */ | |
| 3129 | + { | |
| 3130 | + char *p0 = (char *) strchr (op0->args, '+'); | |
| 3131 | + char *p1 = (char *) strchr (op1->args, '+'); | |
| 3132 | + | |
| 3133 | + if (p0 && p1) | |
| 3134 | + { | |
| 3135 | + /* There is a plus in both operands. Note that a plus | |
| 3136 | + sign cannot be the first character in args, | |
| 3137 | + so the following [-1]'s are valid. */ | |
| 3138 | + if (p0[-1] == 'i' && p1[1] == 'i') | |
| 3139 | + /* op0 is i+1 and op1 is 1+i, so op1 goes first. */ | |
| 3140 | + return 1; | |
| 3141 | + if (p0[1] == 'i' && p1[-1] == 'i') | |
| 3142 | + /* op0 is 1+i and op1 is i+1, so op0 goes first. */ | |
| 3143 | + return -1; | |
| 3144 | + } | |
| 3145 | + } | |
| 3146 | + | |
| 3147 | + /* Put 1,i before i,1. */ | |
| 3148 | + { | |
| 3149 | + int i0 = strncmp (op0->args, "i,1", 3) == 0; | |
| 3150 | + int i1 = strncmp (op1->args, "i,1", 3) == 0; | |
| 3151 | + | |
| 3152 | + if (i0 ^ i1) | |
| 3153 | + return i0 - i1; | |
| 3154 | + } | |
| 3155 | + | |
| 3156 | + /* They are, as far as we can tell, identical. | |
| 3157 | + Since qsort may have rearranged the table partially, there is | |
| 3158 | + no way to tell which one was first in the opcode table as | |
| 3159 | + written, so just say there are equal. */ | |
| 3160 | + /* ??? This is no longer true now that we sort a vector of pointers, | |
| 3161 | + not the table itself. */ | |
| 3162 | + return 0; | |
| 3163 | +} | |
| 3164 | + | |
| 3165 | +/* Build a hash table from the opcode table. | |
| 3166 | + OPCODE_TABLE is a sorted list of pointers into the opcode table. */ | |
| 3167 | + | |
| 3168 | +static void | |
| 3169 | +build_hash_table (opcode_table, hash_table, num_opcodes) | |
| 3170 | + const struct sparc_opcode **opcode_table; | |
| 3171 | + struct opcode_hash **hash_table; | |
| 3172 | + int num_opcodes; | |
| 3173 | +{ | |
| 3174 | + register int i; | |
| 3175 | + int hash_count[HASH_SIZE]; | |
| 3176 | + static struct opcode_hash *hash_buf = NULL; | |
| 3177 | + | |
| 3178 | + /* Start at the end of the table and work backwards so that each | |
| 3179 | + chain is sorted. */ | |
| 3180 | + | |
| 3181 | + memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0])); | |
| 3182 | + memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0])); | |
| 3183 | + if (hash_buf != NULL) | |
| 3184 | + free (hash_buf); | |
| 3185 | + hash_buf = (struct opcode_hash *) malloc (sizeof (struct opcode_hash) * num_opcodes); | |
| 3186 | + for (i = num_opcodes - 1; i >= 0; --i) | |
| 3187 | + { | |
| 3188 | + register int hash = HASH_INSN (opcode_table[i]->match); | |
| 3189 | + register struct opcode_hash *h = &hash_buf[i]; | |
| 3190 | + h->next = hash_table[hash]; | |
| 3191 | + h->opcode = opcode_table[i]; | |
| 3192 | + hash_table[hash] = h; | |
| 3193 | + ++hash_count[hash]; | |
| 3194 | + } | |
| 3195 | + | |
| 3196 | +#if 0 /* for debugging */ | |
| 3197 | + { | |
| 3198 | + int min_count = num_opcodes, max_count = 0; | |
| 3199 | + int total; | |
| 3200 | + | |
| 3201 | + for (i = 0; i < HASH_SIZE; ++i) | |
| 3202 | + { | |
| 3203 | + if (hash_count[i] < min_count) | |
| 3204 | + min_count = hash_count[i]; | |
| 3205 | + if (hash_count[i] > max_count) | |
| 3206 | + max_count = hash_count[i]; | |
| 3207 | + total += hash_count[i]; | |
| 3208 | + } | |
| 3209 | + | |
| 3210 | + printf ("Opcode hash table stats: min %d, max %d, ave %f\n", | |
| 3211 | + min_count, max_count, (double) total / HASH_SIZE); | |
| 3212 | + } | |
| 3213 | +#endif | |
| 3214 | +} | ... | ... |