1 /* CPU data for ip2k. 2 3 THIS FILE IS MACHINE GENERATED WITH CGEN. 4 5 Copyright (C) 1996-2014 Free Software Foundation, Inc. 6 7 This file is part of the GNU Binutils and/or GDB, the GNU debugger. 8 9 This file is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3, or (at your option) 12 any later version. 13 14 It is distributed in the hope that it will be useful, but WITHOUT 15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 17 License for more details. 18 19 You should have received a copy of the GNU General Public License along 20 with this program; if not, write to the Free Software Foundation, Inc., 21 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 22 23 */ 24 25 #include "sysdep.h" 26 #include <stdio.h> 27 #include <stdarg.h> 28 #include "ansidecl.h" 29 #include "bfd.h" 30 #include "symcat.h" 31 #include "ip2k-desc.h" 32 #include "ip2k-opc.h" 33 #include "opintl.h" 34 #include "libiberty.h" 35 #include "xregex.h" 36 37 /* Attributes. */ 38 39 static const CGEN_ATTR_ENTRY bool_attr[] = 40 { 41 { "#f", 0 }, 42 { "#t", 1 }, 43 { 0, 0 } 44 }; 45 46 static const CGEN_ATTR_ENTRY MACH_attr[] ATTRIBUTE_UNUSED = 47 { 48 { "base", MACH_BASE }, 49 { "ip2022", MACH_IP2022 }, 50 { "ip2022ext", MACH_IP2022EXT }, 51 { "max", MACH_MAX }, 52 { 0, 0 } 53 }; 54 55 static const CGEN_ATTR_ENTRY ISA_attr[] ATTRIBUTE_UNUSED = 56 { 57 { "ip2k", ISA_IP2K }, 58 { "max", ISA_MAX }, 59 { 0, 0 } 60 }; 61 62 const CGEN_ATTR_TABLE ip2k_cgen_ifield_attr_table[] = 63 { 64 { "MACH", & MACH_attr[0], & MACH_attr[0] }, 65 { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, 66 { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] }, 67 { "ABS-ADDR", &bool_attr[0], &bool_attr[0] }, 68 { "RESERVED", &bool_attr[0], &bool_attr[0] }, 69 { "SIGN-OPT", &bool_attr[0], &bool_attr[0] }, 70 { "SIGNED", &bool_attr[0], &bool_attr[0] }, 71 { 0, 0, 0 } 72 }; 73 74 const CGEN_ATTR_TABLE ip2k_cgen_hardware_attr_table[] = 75 { 76 { "MACH", & MACH_attr[0], & MACH_attr[0] }, 77 { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, 78 { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] }, 79 { "PC", &bool_attr[0], &bool_attr[0] }, 80 { "PROFILE", &bool_attr[0], &bool_attr[0] }, 81 { 0, 0, 0 } 82 }; 83 84 const CGEN_ATTR_TABLE ip2k_cgen_operand_attr_table[] = 85 { 86 { "MACH", & MACH_attr[0], & MACH_attr[0] }, 87 { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, 88 { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] }, 89 { "ABS-ADDR", &bool_attr[0], &bool_attr[0] }, 90 { "SIGN-OPT", &bool_attr[0], &bool_attr[0] }, 91 { "SIGNED", &bool_attr[0], &bool_attr[0] }, 92 { "NEGATIVE", &bool_attr[0], &bool_attr[0] }, 93 { "RELAX", &bool_attr[0], &bool_attr[0] }, 94 { "SEM-ONLY", &bool_attr[0], &bool_attr[0] }, 95 { 0, 0, 0 } 96 }; 97 98 const CGEN_ATTR_TABLE ip2k_cgen_insn_attr_table[] = 99 { 100 { "MACH", & MACH_attr[0], & MACH_attr[0] }, 101 { "ALIAS", &bool_attr[0], &bool_attr[0] }, 102 { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, 103 { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] }, 104 { "COND-CTI", &bool_attr[0], &bool_attr[0] }, 105 { "SKIP-CTI", &bool_attr[0], &bool_attr[0] }, 106 { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] }, 107 { "RELAXABLE", &bool_attr[0], &bool_attr[0] }, 108 { "RELAXED", &bool_attr[0], &bool_attr[0] }, 109 { "NO-DIS", &bool_attr[0], &bool_attr[0] }, 110 { "PBB", &bool_attr[0], &bool_attr[0] }, 111 { "EXT-SKIP-INSN", &bool_attr[0], &bool_attr[0] }, 112 { "SKIPA", &bool_attr[0], &bool_attr[0] }, 113 { 0, 0, 0 } 114 }; 115 116 /* Instruction set variants. */ 117 118 static const CGEN_ISA ip2k_cgen_isa_table[] = { 119 { "ip2k", 16, 16, 16, 16 }, 120 { 0, 0, 0, 0, 0 } 121 }; 122 123 /* Machine variants. */ 124 125 static const CGEN_MACH ip2k_cgen_mach_table[] = { 126 { "ip2022", "ip2022", MACH_IP2022, 0 }, 127 { "ip2022ext", "ip2022ext", MACH_IP2022EXT, 0 }, 128 { 0, 0, 0, 0 } 129 }; 130 131 static CGEN_KEYWORD_ENTRY ip2k_cgen_opval_register_names_entries[] = 132 { 133 { "ADDRSEL", 2, {0, {{{0, 0}}}}, 0, 0 }, 134 { "ADDRX", 3, {0, {{{0, 0}}}}, 0, 0 }, 135 { "IPH", 4, {0, {{{0, 0}}}}, 0, 0 }, 136 { "IPL", 5, {0, {{{0, 0}}}}, 0, 0 }, 137 { "SPH", 6, {0, {{{0, 0}}}}, 0, 0 }, 138 { "SPL", 7, {0, {{{0, 0}}}}, 0, 0 }, 139 { "PCH", 8, {0, {{{0, 0}}}}, 0, 0 }, 140 { "PCL", 9, {0, {{{0, 0}}}}, 0, 0 }, 141 { "WREG", 10, {0, {{{0, 0}}}}, 0, 0 }, 142 { "STATUS", 11, {0, {{{0, 0}}}}, 0, 0 }, 143 { "DPH", 12, {0, {{{0, 0}}}}, 0, 0 }, 144 { "DPL", 13, {0, {{{0, 0}}}}, 0, 0 }, 145 { "SPDREG", 14, {0, {{{0, 0}}}}, 0, 0 }, 146 { "MULH", 15, {0, {{{0, 0}}}}, 0, 0 }, 147 { "ADDRH", 16, {0, {{{0, 0}}}}, 0, 0 }, 148 { "ADDRL", 17, {0, {{{0, 0}}}}, 0, 0 }, 149 { "DATAH", 18, {0, {{{0, 0}}}}, 0, 0 }, 150 { "DATAL", 19, {0, {{{0, 0}}}}, 0, 0 }, 151 { "INTVECH", 20, {0, {{{0, 0}}}}, 0, 0 }, 152 { "INTVECL", 21, {0, {{{0, 0}}}}, 0, 0 }, 153 { "INTSPD", 22, {0, {{{0, 0}}}}, 0, 0 }, 154 { "INTF", 23, {0, {{{0, 0}}}}, 0, 0 }, 155 { "INTE", 24, {0, {{{0, 0}}}}, 0, 0 }, 156 { "INTED", 25, {0, {{{0, 0}}}}, 0, 0 }, 157 { "FCFG", 26, {0, {{{0, 0}}}}, 0, 0 }, 158 { "TCTRL", 27, {0, {{{0, 0}}}}, 0, 0 }, 159 { "XCFG", 28, {0, {{{0, 0}}}}, 0, 0 }, 160 { "EMCFG", 29, {0, {{{0, 0}}}}, 0, 0 }, 161 { "IPCH", 30, {0, {{{0, 0}}}}, 0, 0 }, 162 { "IPCL", 31, {0, {{{0, 0}}}}, 0, 0 }, 163 { "RAIN", 32, {0, {{{0, 0}}}}, 0, 0 }, 164 { "RAOUT", 33, {0, {{{0, 0}}}}, 0, 0 }, 165 { "RADIR", 34, {0, {{{0, 0}}}}, 0, 0 }, 166 { "LFSRH", 35, {0, {{{0, 0}}}}, 0, 0 }, 167 { "RBIN", 36, {0, {{{0, 0}}}}, 0, 0 }, 168 { "RBOUT", 37, {0, {{{0, 0}}}}, 0, 0 }, 169 { "RBDIR", 38, {0, {{{0, 0}}}}, 0, 0 }, 170 { "LFSRL", 39, {0, {{{0, 0}}}}, 0, 0 }, 171 { "RCIN", 40, {0, {{{0, 0}}}}, 0, 0 }, 172 { "RCOUT", 41, {0, {{{0, 0}}}}, 0, 0 }, 173 { "RCDIR", 42, {0, {{{0, 0}}}}, 0, 0 }, 174 { "LFSRA", 43, {0, {{{0, 0}}}}, 0, 0 }, 175 { "RDIN", 44, {0, {{{0, 0}}}}, 0, 0 }, 176 { "RDOUT", 45, {0, {{{0, 0}}}}, 0, 0 }, 177 { "RDDIR", 46, {0, {{{0, 0}}}}, 0, 0 }, 178 { "REIN", 48, {0, {{{0, 0}}}}, 0, 0 }, 179 { "REOUT", 49, {0, {{{0, 0}}}}, 0, 0 }, 180 { "REDIR", 50, {0, {{{0, 0}}}}, 0, 0 }, 181 { "RFIN", 52, {0, {{{0, 0}}}}, 0, 0 }, 182 { "RFOUT", 53, {0, {{{0, 0}}}}, 0, 0 }, 183 { "RFDIR", 54, {0, {{{0, 0}}}}, 0, 0 }, 184 { "RGOUT", 57, {0, {{{0, 0}}}}, 0, 0 }, 185 { "RGDIR", 58, {0, {{{0, 0}}}}, 0, 0 }, 186 { "RTTMR", 64, {0, {{{0, 0}}}}, 0, 0 }, 187 { "RTCFG", 65, {0, {{{0, 0}}}}, 0, 0 }, 188 { "T0TMR", 66, {0, {{{0, 0}}}}, 0, 0 }, 189 { "T0CFG", 67, {0, {{{0, 0}}}}, 0, 0 }, 190 { "T1CNTH", 68, {0, {{{0, 0}}}}, 0, 0 }, 191 { "T1CNTL", 69, {0, {{{0, 0}}}}, 0, 0 }, 192 { "T1CAP1H", 70, {0, {{{0, 0}}}}, 0, 0 }, 193 { "T1CAP1L", 71, {0, {{{0, 0}}}}, 0, 0 }, 194 { "T1CAP2H", 72, {0, {{{0, 0}}}}, 0, 0 }, 195 { "T1CMP2H", 72, {0, {{{0, 0}}}}, 0, 0 }, 196 { "T1CAP2L", 73, {0, {{{0, 0}}}}, 0, 0 }, 197 { "T1CMP2L", 73, {0, {{{0, 0}}}}, 0, 0 }, 198 { "T1CMP1H", 74, {0, {{{0, 0}}}}, 0, 0 }, 199 { "T1CMP1L", 75, {0, {{{0, 0}}}}, 0, 0 }, 200 { "T1CFG1H", 76, {0, {{{0, 0}}}}, 0, 0 }, 201 { "T1CFG1L", 77, {0, {{{0, 0}}}}, 0, 0 }, 202 { "T1CFG2H", 78, {0, {{{0, 0}}}}, 0, 0 }, 203 { "T1CFG2L", 79, {0, {{{0, 0}}}}, 0, 0 }, 204 { "ADCH", 80, {0, {{{0, 0}}}}, 0, 0 }, 205 { "ADCL", 81, {0, {{{0, 0}}}}, 0, 0 }, 206 { "ADCCFG", 82, {0, {{{0, 0}}}}, 0, 0 }, 207 { "ADCTMR", 83, {0, {{{0, 0}}}}, 0, 0 }, 208 { "T2CNTH", 84, {0, {{{0, 0}}}}, 0, 0 }, 209 { "T2CNTL", 85, {0, {{{0, 0}}}}, 0, 0 }, 210 { "T2CAP1H", 86, {0, {{{0, 0}}}}, 0, 0 }, 211 { "T2CAP1L", 87, {0, {{{0, 0}}}}, 0, 0 }, 212 { "T2CAP2H", 88, {0, {{{0, 0}}}}, 0, 0 }, 213 { "T2CMP2H", 88, {0, {{{0, 0}}}}, 0, 0 }, 214 { "T2CAP2L", 89, {0, {{{0, 0}}}}, 0, 0 }, 215 { "T2CMP2L", 89, {0, {{{0, 0}}}}, 0, 0 }, 216 { "T2CMP1H", 90, {0, {{{0, 0}}}}, 0, 0 }, 217 { "T2CMP1L", 91, {0, {{{0, 0}}}}, 0, 0 }, 218 { "T2CFG1H", 92, {0, {{{0, 0}}}}, 0, 0 }, 219 { "T2CFG1L", 93, {0, {{{0, 0}}}}, 0, 0 }, 220 { "T2CFG2H", 94, {0, {{{0, 0}}}}, 0, 0 }, 221 { "T2CFG2L", 95, {0, {{{0, 0}}}}, 0, 0 }, 222 { "S1TMRH", 96, {0, {{{0, 0}}}}, 0, 0 }, 223 { "S1TMRL", 97, {0, {{{0, 0}}}}, 0, 0 }, 224 { "S1TBUFH", 98, {0, {{{0, 0}}}}, 0, 0 }, 225 { "S1TBUFL", 99, {0, {{{0, 0}}}}, 0, 0 }, 226 { "S1TCFG", 100, {0, {{{0, 0}}}}, 0, 0 }, 227 { "S1RCNT", 101, {0, {{{0, 0}}}}, 0, 0 }, 228 { "S1RBUFH", 102, {0, {{{0, 0}}}}, 0, 0 }, 229 { "S1RBUFL", 103, {0, {{{0, 0}}}}, 0, 0 }, 230 { "S1RCFG", 104, {0, {{{0, 0}}}}, 0, 0 }, 231 { "S1RSYNC", 105, {0, {{{0, 0}}}}, 0, 0 }, 232 { "S1INTF", 106, {0, {{{0, 0}}}}, 0, 0 }, 233 { "S1INTE", 107, {0, {{{0, 0}}}}, 0, 0 }, 234 { "S1MODE", 108, {0, {{{0, 0}}}}, 0, 0 }, 235 { "S1SMASK", 109, {0, {{{0, 0}}}}, 0, 0 }, 236 { "PSPCFG", 110, {0, {{{0, 0}}}}, 0, 0 }, 237 { "CMPCFG", 111, {0, {{{0, 0}}}}, 0, 0 }, 238 { "S2TMRH", 112, {0, {{{0, 0}}}}, 0, 0 }, 239 { "S2TMRL", 113, {0, {{{0, 0}}}}, 0, 0 }, 240 { "S2TBUFH", 114, {0, {{{0, 0}}}}, 0, 0 }, 241 { "S2TBUFL", 115, {0, {{{0, 0}}}}, 0, 0 }, 242 { "S2TCFG", 116, {0, {{{0, 0}}}}, 0, 0 }, 243 { "S2RCNT", 117, {0, {{{0, 0}}}}, 0, 0 }, 244 { "S2RBUFH", 118, {0, {{{0, 0}}}}, 0, 0 }, 245 { "S2RBUFL", 119, {0, {{{0, 0}}}}, 0, 0 }, 246 { "S2RCFG", 120, {0, {{{0, 0}}}}, 0, 0 }, 247 { "S2RSYNC", 121, {0, {{{0, 0}}}}, 0, 0 }, 248 { "S2INTF", 122, {0, {{{0, 0}}}}, 0, 0 }, 249 { "S2INTE", 123, {0, {{{0, 0}}}}, 0, 0 }, 250 { "S2MODE", 124, {0, {{{0, 0}}}}, 0, 0 }, 251 { "S2SMASK", 125, {0, {{{0, 0}}}}, 0, 0 }, 252 { "CALLH", 126, {0, {{{0, 0}}}}, 0, 0 }, 253 { "CALLL", 127, {0, {{{0, 0}}}}, 0, 0 } 254 }; 255 256 CGEN_KEYWORD ip2k_cgen_opval_register_names = 257 { 258 & ip2k_cgen_opval_register_names_entries[0], 259 121, 260 0, 0, 0, 0, "" 261 }; 262 263 264 /* The hardware table. */ 265 266 #define A(a) (1 << CGEN_HW_##a) 267 268 const CGEN_HW_ENTRY ip2k_cgen_hw_table[] = 269 { 270 { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 271 { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 272 { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 273 { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 274 { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 275 { "h-spr", HW_H_SPR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 276 { "h-registers", HW_H_REGISTERS, CGEN_ASM_NONE, 0, { 0|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } } }, 277 { "h-stack", HW_H_STACK, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 278 { "h-pabits", HW_H_PABITS, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 279 { "h-zbit", HW_H_ZBIT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 280 { "h-cbit", HW_H_CBIT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 281 { "h-dcbit", HW_H_DCBIT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 282 { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PROFILE)|A(PC), { { { (1<<MACH_BASE), 0 } } } } }, 283 { 0, 0, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } } 284 }; 285 286 #undef A 287 288 289 /* The instruction field table. */ 290 291 #define A(a) (1 << CGEN_IFLD_##a) 292 293 const CGEN_IFLD ip2k_cgen_ifld_table[] = 294 { 295 { IP2K_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 296 { IP2K_F_ANYOF, "f-anyof", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 297 { IP2K_F_IMM8, "f-imm8", 0, 16, 7, 8, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 298 { IP2K_F_REG, "f-reg", 0, 16, 8, 9, { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } } }, 299 { IP2K_F_ADDR16CJP, "f-addr16cjp", 0, 16, 12, 13, { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } } }, 300 { IP2K_F_DIR, "f-dir", 0, 16, 9, 1, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 301 { IP2K_F_BITNO, "f-bitno", 0, 16, 11, 3, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 302 { IP2K_F_OP3, "f-op3", 0, 16, 15, 3, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 303 { IP2K_F_OP4, "f-op4", 0, 16, 15, 4, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 304 { IP2K_F_OP4MID, "f-op4mid", 0, 16, 11, 4, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 305 { IP2K_F_OP6, "f-op6", 0, 16, 15, 6, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 306 { IP2K_F_OP8, "f-op8", 0, 16, 15, 8, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 307 { IP2K_F_OP6_10LOW, "f-op6-10low", 0, 16, 9, 10, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 308 { IP2K_F_OP6_7LOW, "f-op6-7low", 0, 16, 9, 7, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 309 { IP2K_F_RETI3, "f-reti3", 0, 16, 2, 3, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 310 { IP2K_F_SKIPB, "f-skipb", 0, 16, 12, 1, { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } } }, 311 { IP2K_F_PAGE3, "f-page3", 0, 16, 2, 3, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 312 { 0, 0, 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } } 313 }; 314 315 #undef A 316 317 318 319 /* multi ifield declarations */ 320 321 322 323 /* multi ifield definitions */ 324 325 326 /* The operand table. */ 327 328 #define A(a) (1 << CGEN_OPERAND_##a) 329 #define OPERAND(op) IP2K_OPERAND_##op 330 331 const CGEN_OPERAND ip2k_cgen_operand_table[] = 332 { 333 /* pc: program counter */ 334 { "pc", IP2K_OPERAND_PC, HW_H_PC, 0, 0, 335 { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_NIL] } }, 336 { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } } }, 337 /* addr16cjp: 13-bit address */ 338 { "addr16cjp", IP2K_OPERAND_ADDR16CJP, HW_H_UINT, 12, 13, 339 { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_ADDR16CJP] } }, 340 { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } } }, 341 /* fr: register */ 342 { "fr", IP2K_OPERAND_FR, HW_H_REGISTERS, 8, 9, 343 { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_REG] } }, 344 { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } } }, 345 /* lit8: 8-bit signed literal */ 346 { "lit8", IP2K_OPERAND_LIT8, HW_H_SINT, 7, 8, 347 { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_IMM8] } }, 348 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 349 /* bitno: bit number */ 350 { "bitno", IP2K_OPERAND_BITNO, HW_H_UINT, 11, 3, 351 { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_BITNO] } }, 352 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 353 /* addr16p: page number */ 354 { "addr16p", IP2K_OPERAND_ADDR16P, HW_H_UINT, 2, 3, 355 { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_PAGE3] } }, 356 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 357 /* addr16h: high 8 bits of address */ 358 { "addr16h", IP2K_OPERAND_ADDR16H, HW_H_UINT, 7, 8, 359 { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_IMM8] } }, 360 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 361 /* addr16l: low 8 bits of address */ 362 { "addr16l", IP2K_OPERAND_ADDR16L, HW_H_UINT, 7, 8, 363 { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_IMM8] } }, 364 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 365 /* reti3: reti flags */ 366 { "reti3", IP2K_OPERAND_RETI3, HW_H_UINT, 2, 3, 367 { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_RETI3] } }, 368 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 369 /* pabits: page bits */ 370 { "pabits", IP2K_OPERAND_PABITS, HW_H_PABITS, 0, 0, 371 { 0, { (const PTR) 0 } }, 372 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 373 /* zbit: zero bit */ 374 { "zbit", IP2K_OPERAND_ZBIT, HW_H_ZBIT, 0, 0, 375 { 0, { (const PTR) 0 } }, 376 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 377 /* cbit: carry bit */ 378 { "cbit", IP2K_OPERAND_CBIT, HW_H_CBIT, 0, 0, 379 { 0, { (const PTR) 0 } }, 380 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 381 /* dcbit: digit carry bit */ 382 { "dcbit", IP2K_OPERAND_DCBIT, HW_H_DCBIT, 0, 0, 383 { 0, { (const PTR) 0 } }, 384 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 385 /* sentinel */ 386 { 0, 0, 0, 0, 0, 387 { 0, { (const PTR) 0 } }, 388 { 0, { { { (1<<MACH_BASE), 0 } } } } } 389 }; 390 391 #undef A 392 393 394 /* The instruction table. */ 395 396 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field)) 397 #define A(a) (1 << CGEN_INSN_##a) 398 399 static const CGEN_IBASE ip2k_cgen_insn_table[MAX_INSNS] = 400 { 401 /* Special null first entry. 402 A `num' value of zero is thus invalid. 403 Also, the special `invalid' insn resides here. */ 404 { 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 405 /* jmp $addr16cjp */ 406 { 407 IP2K_INSN_JMP, "jmp", "jmp", 16, 408 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 409 }, 410 /* call $addr16cjp */ 411 { 412 IP2K_INSN_CALL, "call", "call", 16, 413 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 414 }, 415 /* sb $fr,$bitno */ 416 { 417 IP2K_INSN_SB, "sb", "sb", 16, 418 { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } } 419 }, 420 /* snb $fr,$bitno */ 421 { 422 IP2K_INSN_SNB, "snb", "snb", 16, 423 { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } } 424 }, 425 /* setb $fr,$bitno */ 426 { 427 IP2K_INSN_SETB, "setb", "setb", 16, 428 { 0, { { { (1<<MACH_BASE), 0 } } } } 429 }, 430 /* clrb $fr,$bitno */ 431 { 432 IP2K_INSN_CLRB, "clrb", "clrb", 16, 433 { 0, { { { (1<<MACH_BASE), 0 } } } } 434 }, 435 /* xor W,#$lit8 */ 436 { 437 IP2K_INSN_XORW_L, "xorw_l", "xor", 16, 438 { 0, { { { (1<<MACH_BASE), 0 } } } } 439 }, 440 /* and W,#$lit8 */ 441 { 442 IP2K_INSN_ANDW_L, "andw_l", "and", 16, 443 { 0, { { { (1<<MACH_BASE), 0 } } } } 444 }, 445 /* or W,#$lit8 */ 446 { 447 IP2K_INSN_ORW_L, "orw_l", "or", 16, 448 { 0, { { { (1<<MACH_BASE), 0 } } } } 449 }, 450 /* add W,#$lit8 */ 451 { 452 IP2K_INSN_ADDW_L, "addw_l", "add", 16, 453 { 0, { { { (1<<MACH_BASE), 0 } } } } 454 }, 455 /* sub W,#$lit8 */ 456 { 457 IP2K_INSN_SUBW_L, "subw_l", "sub", 16, 458 { 0, { { { (1<<MACH_BASE), 0 } } } } 459 }, 460 /* cmp W,#$lit8 */ 461 { 462 IP2K_INSN_CMPW_L, "cmpw_l", "cmp", 16, 463 { 0, { { { (1<<MACH_BASE), 0 } } } } 464 }, 465 /* retw #$lit8 */ 466 { 467 IP2K_INSN_RETW_L, "retw_l", "retw", 16, 468 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 469 }, 470 /* cse W,#$lit8 */ 471 { 472 IP2K_INSN_CSEW_L, "csew_l", "cse", 16, 473 { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } } 474 }, 475 /* csne W,#$lit8 */ 476 { 477 IP2K_INSN_CSNEW_L, "csnew_l", "csne", 16, 478 { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } } 479 }, 480 /* push #$lit8 */ 481 { 482 IP2K_INSN_PUSH_L, "push_l", "push", 16, 483 { 0, { { { (1<<MACH_BASE), 0 } } } } 484 }, 485 /* muls W,#$lit8 */ 486 { 487 IP2K_INSN_MULSW_L, "mulsw_l", "muls", 16, 488 { 0, { { { (1<<MACH_BASE), 0 } } } } 489 }, 490 /* mulu W,#$lit8 */ 491 { 492 IP2K_INSN_MULUW_L, "muluw_l", "mulu", 16, 493 { 0, { { { (1<<MACH_BASE), 0 } } } } 494 }, 495 /* loadl #$lit8 */ 496 { 497 IP2K_INSN_LOADL_L, "loadl_l", "loadl", 16, 498 { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } } 499 }, 500 /* loadh #$lit8 */ 501 { 502 IP2K_INSN_LOADH_L, "loadh_l", "loadh", 16, 503 { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } } 504 }, 505 /* loadl $addr16l */ 506 { 507 IP2K_INSN_LOADL_A, "loadl_a", "loadl", 16, 508 { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } } 509 }, 510 /* loadh $addr16h */ 511 { 512 IP2K_INSN_LOADH_A, "loadh_a", "loadh", 16, 513 { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } } 514 }, 515 /* addc $fr,W */ 516 { 517 IP2K_INSN_ADDCFR_W, "addcfr_w", "addc", 16, 518 { 0, { { { (1<<MACH_BASE), 0 } } } } 519 }, 520 /* addc W,$fr */ 521 { 522 IP2K_INSN_ADDCW_FR, "addcw_fr", "addc", 16, 523 { 0, { { { (1<<MACH_BASE), 0 } } } } 524 }, 525 /* incsnz $fr */ 526 { 527 IP2K_INSN_INCSNZ_FR, "incsnz_fr", "incsnz", 16, 528 { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } } 529 }, 530 /* incsnz W,$fr */ 531 { 532 IP2K_INSN_INCSNZW_FR, "incsnzw_fr", "incsnz", 16, 533 { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } } 534 }, 535 /* muls W,$fr */ 536 { 537 IP2K_INSN_MULSW_FR, "mulsw_fr", "muls", 16, 538 { 0, { { { (1<<MACH_BASE), 0 } } } } 539 }, 540 /* mulu W,$fr */ 541 { 542 IP2K_INSN_MULUW_FR, "muluw_fr", "mulu", 16, 543 { 0, { { { (1<<MACH_BASE), 0 } } } } 544 }, 545 /* decsnz $fr */ 546 { 547 IP2K_INSN_DECSNZ_FR, "decsnz_fr", "decsnz", 16, 548 { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } } 549 }, 550 /* decsnz W,$fr */ 551 { 552 IP2K_INSN_DECSNZW_FR, "decsnzw_fr", "decsnz", 16, 553 { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } } 554 }, 555 /* subc W,$fr */ 556 { 557 IP2K_INSN_SUBCW_FR, "subcw_fr", "subc", 16, 558 { 0, { { { (1<<MACH_BASE), 0 } } } } 559 }, 560 /* subc $fr,W */ 561 { 562 IP2K_INSN_SUBCFR_W, "subcfr_w", "subc", 16, 563 { 0, { { { (1<<MACH_BASE), 0 } } } } 564 }, 565 /* pop $fr */ 566 { 567 IP2K_INSN_POP_FR, "pop_fr", "pop", 16, 568 { 0, { { { (1<<MACH_BASE), 0 } } } } 569 }, 570 /* push $fr */ 571 { 572 IP2K_INSN_PUSH_FR, "push_fr", "push", 16, 573 { 0, { { { (1<<MACH_BASE), 0 } } } } 574 }, 575 /* cse W,$fr */ 576 { 577 IP2K_INSN_CSEW_FR, "csew_fr", "cse", 16, 578 { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } } 579 }, 580 /* csne W,$fr */ 581 { 582 IP2K_INSN_CSNEW_FR, "csnew_fr", "csne", 16, 583 { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } } 584 }, 585 /* incsz $fr */ 586 { 587 IP2K_INSN_INCSZ_FR, "incsz_fr", "incsz", 16, 588 { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } } 589 }, 590 /* incsz W,$fr */ 591 { 592 IP2K_INSN_INCSZW_FR, "incszw_fr", "incsz", 16, 593 { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } } 594 }, 595 /* swap $fr */ 596 { 597 IP2K_INSN_SWAP_FR, "swap_fr", "swap", 16, 598 { 0, { { { (1<<MACH_BASE), 0 } } } } 599 }, 600 /* swap W,$fr */ 601 { 602 IP2K_INSN_SWAPW_FR, "swapw_fr", "swap", 16, 603 { 0, { { { (1<<MACH_BASE), 0 } } } } 604 }, 605 /* rl $fr */ 606 { 607 IP2K_INSN_RL_FR, "rl_fr", "rl", 16, 608 { 0, { { { (1<<MACH_BASE), 0 } } } } 609 }, 610 /* rl W,$fr */ 611 { 612 IP2K_INSN_RLW_FR, "rlw_fr", "rl", 16, 613 { 0, { { { (1<<MACH_BASE), 0 } } } } 614 }, 615 /* rr $fr */ 616 { 617 IP2K_INSN_RR_FR, "rr_fr", "rr", 16, 618 { 0, { { { (1<<MACH_BASE), 0 } } } } 619 }, 620 /* rr W,$fr */ 621 { 622 IP2K_INSN_RRW_FR, "rrw_fr", "rr", 16, 623 { 0, { { { (1<<MACH_BASE), 0 } } } } 624 }, 625 /* decsz $fr */ 626 { 627 IP2K_INSN_DECSZ_FR, "decsz_fr", "decsz", 16, 628 { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } } 629 }, 630 /* decsz W,$fr */ 631 { 632 IP2K_INSN_DECSZW_FR, "decszw_fr", "decsz", 16, 633 { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } } 634 }, 635 /* inc $fr */ 636 { 637 IP2K_INSN_INC_FR, "inc_fr", "inc", 16, 638 { 0, { { { (1<<MACH_BASE), 0 } } } } 639 }, 640 /* inc W,$fr */ 641 { 642 IP2K_INSN_INCW_FR, "incw_fr", "inc", 16, 643 { 0, { { { (1<<MACH_BASE), 0 } } } } 644 }, 645 /* not $fr */ 646 { 647 IP2K_INSN_NOT_FR, "not_fr", "not", 16, 648 { 0, { { { (1<<MACH_BASE), 0 } } } } 649 }, 650 /* not W,$fr */ 651 { 652 IP2K_INSN_NOTW_FR, "notw_fr", "not", 16, 653 { 0, { { { (1<<MACH_BASE), 0 } } } } 654 }, 655 /* test $fr */ 656 { 657 IP2K_INSN_TEST_FR, "test_fr", "test", 16, 658 { 0, { { { (1<<MACH_BASE), 0 } } } } 659 }, 660 /* mov W,#$lit8 */ 661 { 662 IP2K_INSN_MOVW_L, "movw_l", "mov", 16, 663 { 0, { { { (1<<MACH_BASE), 0 } } } } 664 }, 665 /* mov $fr,W */ 666 { 667 IP2K_INSN_MOVFR_W, "movfr_w", "mov", 16, 668 { 0, { { { (1<<MACH_BASE), 0 } } } } 669 }, 670 /* mov W,$fr */ 671 { 672 IP2K_INSN_MOVW_FR, "movw_fr", "mov", 16, 673 { 0, { { { (1<<MACH_BASE), 0 } } } } 674 }, 675 /* add $fr,W */ 676 { 677 IP2K_INSN_ADDFR_W, "addfr_w", "add", 16, 678 { 0, { { { (1<<MACH_BASE), 0 } } } } 679 }, 680 /* add W,$fr */ 681 { 682 IP2K_INSN_ADDW_FR, "addw_fr", "add", 16, 683 { 0, { { { (1<<MACH_BASE), 0 } } } } 684 }, 685 /* xor $fr,W */ 686 { 687 IP2K_INSN_XORFR_W, "xorfr_w", "xor", 16, 688 { 0, { { { (1<<MACH_BASE), 0 } } } } 689 }, 690 /* xor W,$fr */ 691 { 692 IP2K_INSN_XORW_FR, "xorw_fr", "xor", 16, 693 { 0, { { { (1<<MACH_BASE), 0 } } } } 694 }, 695 /* and $fr,W */ 696 { 697 IP2K_INSN_ANDFR_W, "andfr_w", "and", 16, 698 { 0, { { { (1<<MACH_BASE), 0 } } } } 699 }, 700 /* and W,$fr */ 701 { 702 IP2K_INSN_ANDW_FR, "andw_fr", "and", 16, 703 { 0, { { { (1<<MACH_BASE), 0 } } } } 704 }, 705 /* or $fr,W */ 706 { 707 IP2K_INSN_ORFR_W, "orfr_w", "or", 16, 708 { 0, { { { (1<<MACH_BASE), 0 } } } } 709 }, 710 /* or W,$fr */ 711 { 712 IP2K_INSN_ORW_FR, "orw_fr", "or", 16, 713 { 0, { { { (1<<MACH_BASE), 0 } } } } 714 }, 715 /* dec $fr */ 716 { 717 IP2K_INSN_DEC_FR, "dec_fr", "dec", 16, 718 { 0, { { { (1<<MACH_BASE), 0 } } } } 719 }, 720 /* dec W,$fr */ 721 { 722 IP2K_INSN_DECW_FR, "decw_fr", "dec", 16, 723 { 0, { { { (1<<MACH_BASE), 0 } } } } 724 }, 725 /* sub $fr,W */ 726 { 727 IP2K_INSN_SUBFR_W, "subfr_w", "sub", 16, 728 { 0, { { { (1<<MACH_BASE), 0 } } } } 729 }, 730 /* sub W,$fr */ 731 { 732 IP2K_INSN_SUBW_FR, "subw_fr", "sub", 16, 733 { 0, { { { (1<<MACH_BASE), 0 } } } } 734 }, 735 /* clr $fr */ 736 { 737 IP2K_INSN_CLR_FR, "clr_fr", "clr", 16, 738 { 0, { { { (1<<MACH_BASE), 0 } } } } 739 }, 740 /* cmp W,$fr */ 741 { 742 IP2K_INSN_CMPW_FR, "cmpw_fr", "cmp", 16, 743 { 0, { { { (1<<MACH_BASE), 0 } } } } 744 }, 745 /* speed #$lit8 */ 746 { 747 IP2K_INSN_SPEED, "speed", "speed", 16, 748 { 0, { { { (1<<MACH_BASE), 0 } } } } 749 }, 750 /* ireadi */ 751 { 752 IP2K_INSN_IREADI, "ireadi", "ireadi", 16, 753 { 0, { { { (1<<MACH_BASE), 0 } } } } 754 }, 755 /* iwritei */ 756 { 757 IP2K_INSN_IWRITEI, "iwritei", "iwritei", 16, 758 { 0, { { { (1<<MACH_BASE), 0 } } } } 759 }, 760 /* fread */ 761 { 762 IP2K_INSN_FREAD, "fread", "fread", 16, 763 { 0, { { { (1<<MACH_BASE), 0 } } } } 764 }, 765 /* fwrite */ 766 { 767 IP2K_INSN_FWRITE, "fwrite", "fwrite", 16, 768 { 0, { { { (1<<MACH_BASE), 0 } } } } 769 }, 770 /* iread */ 771 { 772 IP2K_INSN_IREAD, "iread", "iread", 16, 773 { 0, { { { (1<<MACH_BASE), 0 } } } } 774 }, 775 /* iwrite */ 776 { 777 IP2K_INSN_IWRITE, "iwrite", "iwrite", 16, 778 { 0, { { { (1<<MACH_BASE), 0 } } } } 779 }, 780 /* page $addr16p */ 781 { 782 IP2K_INSN_PAGE, "page", "page", 16, 783 { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } } 784 }, 785 /* system */ 786 { 787 IP2K_INSN_SYSTEM, "system", "system", 16, 788 { 0, { { { (1<<MACH_BASE), 0 } } } } 789 }, 790 /* reti #$reti3 */ 791 { 792 IP2K_INSN_RETI, "reti", "reti", 16, 793 { 0, { { { (1<<MACH_BASE), 0 } } } } 794 }, 795 /* ret */ 796 { 797 IP2K_INSN_RET, "ret", "ret", 16, 798 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 799 }, 800 /* int */ 801 { 802 IP2K_INSN_INT, "int", "int", 16, 803 { 0, { { { (1<<MACH_BASE), 0 } } } } 804 }, 805 /* breakx */ 806 { 807 IP2K_INSN_BREAKX, "breakx", "breakx", 16, 808 { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } } 809 }, 810 /* cwdt */ 811 { 812 IP2K_INSN_CWDT, "cwdt", "cwdt", 16, 813 { 0, { { { (1<<MACH_BASE), 0 } } } } 814 }, 815 /* ferase */ 816 { 817 IP2K_INSN_FERASE, "ferase", "ferase", 16, 818 { 0, { { { (1<<MACH_BASE), 0 } } } } 819 }, 820 /* retnp */ 821 { 822 IP2K_INSN_RETNP, "retnp", "retnp", 16, 823 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 824 }, 825 /* break */ 826 { 827 IP2K_INSN_BREAK, "break", "break", 16, 828 { 0, { { { (1<<MACH_BASE), 0 } } } } 829 }, 830 /* nop */ 831 { 832 IP2K_INSN_NOP, "nop", "nop", 16, 833 { 0, { { { (1<<MACH_BASE), 0 } } } } 834 }, 835 }; 836 837 #undef OP 838 #undef A 839 840 /* Initialize anything needed to be done once, before any cpu_open call. */ 841 842 static void 843 init_tables (void) 844 { 845 } 846 847 static const CGEN_MACH * lookup_mach_via_bfd_name (const CGEN_MACH *, const char *); 848 static void build_hw_table (CGEN_CPU_TABLE *); 849 static void build_ifield_table (CGEN_CPU_TABLE *); 850 static void build_operand_table (CGEN_CPU_TABLE *); 851 static void build_insn_table (CGEN_CPU_TABLE *); 852 static void ip2k_cgen_rebuild_tables (CGEN_CPU_TABLE *); 853 854 /* Subroutine of ip2k_cgen_cpu_open to look up a mach via its bfd name. */ 855 856 static const CGEN_MACH * 857 lookup_mach_via_bfd_name (const CGEN_MACH *table, const char *name) 858 { 859 while (table->name) 860 { 861 if (strcmp (name, table->bfd_name) == 0) 862 return table; 863 ++table; 864 } 865 abort (); 866 } 867 868 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table. */ 869 870 static void 871 build_hw_table (CGEN_CPU_TABLE *cd) 872 { 873 int i; 874 int machs = cd->machs; 875 const CGEN_HW_ENTRY *init = & ip2k_cgen_hw_table[0]; 876 /* MAX_HW is only an upper bound on the number of selected entries. 877 However each entry is indexed by it's enum so there can be holes in 878 the table. */ 879 const CGEN_HW_ENTRY **selected = 880 (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *)); 881 882 cd->hw_table.init_entries = init; 883 cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY); 884 memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *)); 885 /* ??? For now we just use machs to determine which ones we want. */ 886 for (i = 0; init[i].name != NULL; ++i) 887 if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH) 888 & machs) 889 selected[init[i].type] = &init[i]; 890 cd->hw_table.entries = selected; 891 cd->hw_table.num_entries = MAX_HW; 892 } 893 894 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table. */ 895 896 static void 897 build_ifield_table (CGEN_CPU_TABLE *cd) 898 { 899 cd->ifld_table = & ip2k_cgen_ifld_table[0]; 900 } 901 902 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table. */ 903 904 static void 905 build_operand_table (CGEN_CPU_TABLE *cd) 906 { 907 int i; 908 int machs = cd->machs; 909 const CGEN_OPERAND *init = & ip2k_cgen_operand_table[0]; 910 /* MAX_OPERANDS is only an upper bound on the number of selected entries. 911 However each entry is indexed by it's enum so there can be holes in 912 the table. */ 913 const CGEN_OPERAND **selected = xmalloc (MAX_OPERANDS * sizeof (* selected)); 914 915 cd->operand_table.init_entries = init; 916 cd->operand_table.entry_size = sizeof (CGEN_OPERAND); 917 memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *)); 918 /* ??? For now we just use mach to determine which ones we want. */ 919 for (i = 0; init[i].name != NULL; ++i) 920 if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH) 921 & machs) 922 selected[init[i].type] = &init[i]; 923 cd->operand_table.entries = selected; 924 cd->operand_table.num_entries = MAX_OPERANDS; 925 } 926 927 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table. 928 ??? This could leave out insns not supported by the specified mach/isa, 929 but that would cause errors like "foo only supported by bar" to become 930 "unknown insn", so for now we include all insns and require the app to 931 do the checking later. 932 ??? On the other hand, parsing of such insns may require their hardware or 933 operand elements to be in the table [which they mightn't be]. */ 934 935 static void 936 build_insn_table (CGEN_CPU_TABLE *cd) 937 { 938 int i; 939 const CGEN_IBASE *ib = & ip2k_cgen_insn_table[0]; 940 CGEN_INSN *insns = xmalloc (MAX_INSNS * sizeof (CGEN_INSN)); 941 942 memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN)); 943 for (i = 0; i < MAX_INSNS; ++i) 944 insns[i].base = &ib[i]; 945 cd->insn_table.init_entries = insns; 946 cd->insn_table.entry_size = sizeof (CGEN_IBASE); 947 cd->insn_table.num_init_entries = MAX_INSNS; 948 } 949 950 /* Subroutine of ip2k_cgen_cpu_open to rebuild the tables. */ 951 952 static void 953 ip2k_cgen_rebuild_tables (CGEN_CPU_TABLE *cd) 954 { 955 int i; 956 CGEN_BITSET *isas = cd->isas; 957 unsigned int machs = cd->machs; 958 959 cd->int_insn_p = CGEN_INT_INSN_P; 960 961 /* Data derived from the isa spec. */ 962 #define UNSET (CGEN_SIZE_UNKNOWN + 1) 963 cd->default_insn_bitsize = UNSET; 964 cd->base_insn_bitsize = UNSET; 965 cd->min_insn_bitsize = 65535; /* Some ridiculously big number. */ 966 cd->max_insn_bitsize = 0; 967 for (i = 0; i < MAX_ISAS; ++i) 968 if (cgen_bitset_contains (isas, i)) 969 { 970 const CGEN_ISA *isa = & ip2k_cgen_isa_table[i]; 971 972 /* Default insn sizes of all selected isas must be 973 equal or we set the result to 0, meaning "unknown". */ 974 if (cd->default_insn_bitsize == UNSET) 975 cd->default_insn_bitsize = isa->default_insn_bitsize; 976 else if (isa->default_insn_bitsize == cd->default_insn_bitsize) 977 ; /* This is ok. */ 978 else 979 cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN; 980 981 /* Base insn sizes of all selected isas must be equal 982 or we set the result to 0, meaning "unknown". */ 983 if (cd->base_insn_bitsize == UNSET) 984 cd->base_insn_bitsize = isa->base_insn_bitsize; 985 else if (isa->base_insn_bitsize == cd->base_insn_bitsize) 986 ; /* This is ok. */ 987 else 988 cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN; 989 990 /* Set min,max insn sizes. */ 991 if (isa->min_insn_bitsize < cd->min_insn_bitsize) 992 cd->min_insn_bitsize = isa->min_insn_bitsize; 993 if (isa->max_insn_bitsize > cd->max_insn_bitsize) 994 cd->max_insn_bitsize = isa->max_insn_bitsize; 995 } 996 997 /* Data derived from the mach spec. */ 998 for (i = 0; i < MAX_MACHS; ++i) 999 if (((1 << i) & machs) != 0) 1000 { 1001 const CGEN_MACH *mach = & ip2k_cgen_mach_table[i]; 1002 1003 if (mach->insn_chunk_bitsize != 0) 1004 { 1005 if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize) 1006 { 1007 fprintf (stderr, "ip2k_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n", 1008 cd->insn_chunk_bitsize, mach->insn_chunk_bitsize); 1009 abort (); 1010 } 1011 1012 cd->insn_chunk_bitsize = mach->insn_chunk_bitsize; 1013 } 1014 } 1015 1016 /* Determine which hw elements are used by MACH. */ 1017 build_hw_table (cd); 1018 1019 /* Build the ifield table. */ 1020 build_ifield_table (cd); 1021 1022 /* Determine which operands are used by MACH/ISA. */ 1023 build_operand_table (cd); 1024 1025 /* Build the instruction table. */ 1026 build_insn_table (cd); 1027 } 1028 1029 /* Initialize a cpu table and return a descriptor. 1030 It's much like opening a file, and must be the first function called. 1031 The arguments are a set of (type/value) pairs, terminated with 1032 CGEN_CPU_OPEN_END. 1033 1034 Currently supported values: 1035 CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr 1036 CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr 1037 CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name 1038 CGEN_CPU_OPEN_ENDIAN: specify endian choice 1039 CGEN_CPU_OPEN_END: terminates arguments 1040 1041 ??? Simultaneous multiple isas might not make sense, but it's not (yet) 1042 precluded. */ 1043 1044 CGEN_CPU_DESC 1045 ip2k_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...) 1046 { 1047 CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE)); 1048 static int init_p; 1049 CGEN_BITSET *isas = 0; /* 0 = "unspecified" */ 1050 unsigned int machs = 0; /* 0 = "unspecified" */ 1051 enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN; 1052 va_list ap; 1053 1054 if (! init_p) 1055 { 1056 init_tables (); 1057 init_p = 1; 1058 } 1059 1060 memset (cd, 0, sizeof (*cd)); 1061 1062 va_start (ap, arg_type); 1063 while (arg_type != CGEN_CPU_OPEN_END) 1064 { 1065 switch (arg_type) 1066 { 1067 case CGEN_CPU_OPEN_ISAS : 1068 isas = va_arg (ap, CGEN_BITSET *); 1069 break; 1070 case CGEN_CPU_OPEN_MACHS : 1071 machs = va_arg (ap, unsigned int); 1072 break; 1073 case CGEN_CPU_OPEN_BFDMACH : 1074 { 1075 const char *name = va_arg (ap, const char *); 1076 const CGEN_MACH *mach = 1077 lookup_mach_via_bfd_name (ip2k_cgen_mach_table, name); 1078 1079 machs |= 1 << mach->num; 1080 break; 1081 } 1082 case CGEN_CPU_OPEN_ENDIAN : 1083 endian = va_arg (ap, enum cgen_endian); 1084 break; 1085 default : 1086 fprintf (stderr, "ip2k_cgen_cpu_open: unsupported argument `%d'\n", 1087 arg_type); 1088 abort (); /* ??? return NULL? */ 1089 } 1090 arg_type = va_arg (ap, enum cgen_cpu_open_arg); 1091 } 1092 va_end (ap); 1093 1094 /* Mach unspecified means "all". */ 1095 if (machs == 0) 1096 machs = (1 << MAX_MACHS) - 1; 1097 /* Base mach is always selected. */ 1098 machs |= 1; 1099 if (endian == CGEN_ENDIAN_UNKNOWN) 1100 { 1101 /* ??? If target has only one, could have a default. */ 1102 fprintf (stderr, "ip2k_cgen_cpu_open: no endianness specified\n"); 1103 abort (); 1104 } 1105 1106 cd->isas = cgen_bitset_copy (isas); 1107 cd->machs = machs; 1108 cd->endian = endian; 1109 /* FIXME: for the sparc case we can determine insn-endianness statically. 1110 The worry here is where both data and insn endian can be independently 1111 chosen, in which case this function will need another argument. 1112 Actually, will want to allow for more arguments in the future anyway. */ 1113 cd->insn_endian = endian; 1114 1115 /* Table (re)builder. */ 1116 cd->rebuild_tables = ip2k_cgen_rebuild_tables; 1117 ip2k_cgen_rebuild_tables (cd); 1118 1119 /* Default to not allowing signed overflow. */ 1120 cd->signed_overflow_ok_p = 0; 1121 1122 return (CGEN_CPU_DESC) cd; 1123 } 1124 1125 /* Cover fn to ip2k_cgen_cpu_open to handle the simple case of 1 isa, 1 mach. 1126 MACH_NAME is the bfd name of the mach. */ 1127 1128 CGEN_CPU_DESC 1129 ip2k_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian) 1130 { 1131 return ip2k_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name, 1132 CGEN_CPU_OPEN_ENDIAN, endian, 1133 CGEN_CPU_OPEN_END); 1134 } 1135 1136 /* Close a cpu table. 1137 ??? This can live in a machine independent file, but there's currently 1138 no place to put this file (there's no libcgen). libopcodes is the wrong 1139 place as some simulator ports use this but they don't use libopcodes. */ 1140 1141 void 1142 ip2k_cgen_cpu_close (CGEN_CPU_DESC cd) 1143 { 1144 unsigned int i; 1145 const CGEN_INSN *insns; 1146 1147 if (cd->macro_insn_table.init_entries) 1148 { 1149 insns = cd->macro_insn_table.init_entries; 1150 for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns) 1151 if (CGEN_INSN_RX ((insns))) 1152 regfree (CGEN_INSN_RX (insns)); 1153 } 1154 1155 if (cd->insn_table.init_entries) 1156 { 1157 insns = cd->insn_table.init_entries; 1158 for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns) 1159 if (CGEN_INSN_RX (insns)) 1160 regfree (CGEN_INSN_RX (insns)); 1161 } 1162 1163 if (cd->macro_insn_table.init_entries) 1164 free ((CGEN_INSN *) cd->macro_insn_table.init_entries); 1165 1166 if (cd->insn_table.init_entries) 1167 free ((CGEN_INSN *) cd->insn_table.init_entries); 1168 1169 if (cd->hw_table.entries) 1170 free ((CGEN_HW_ENTRY *) cd->hw_table.entries); 1171 1172 if (cd->operand_table.entries) 1173 free ((CGEN_HW_ENTRY *) cd->operand_table.entries); 1174 1175 free (cd); 1176 } 1177 1178