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