1 1.1.1.5 christos /* DO NOT EDIT! -*- buffer-read-only: t -*- vi:set ro: */ 2 1.1 christos /* Instruction building/extraction support for m32r. -*- C -*- 3 1.1 christos 4 1.1 christos THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator. 5 1.1 christos - the resultant file is machine generated, cgen-ibld.in isn't 6 1.1 christos 7 1.1.1.9 christos Copyright (C) 1996-2025 Free Software Foundation, Inc. 8 1.1 christos 9 1.1 christos This file is part of libopcodes. 10 1.1 christos 11 1.1 christos This library is free software; you can redistribute it and/or modify 12 1.1 christos it under the terms of the GNU General Public License as published by 13 1.1 christos the Free Software Foundation; either version 3, or (at your option) 14 1.1 christos any later version. 15 1.1 christos 16 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT 17 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 1.1 christos License for more details. 20 1.1 christos 21 1.1 christos You should have received a copy of the GNU General Public License 22 1.1 christos along with this program; if not, write to the Free Software Foundation, Inc., 23 1.1 christos 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 24 1.1 christos 25 1.1 christos /* ??? Eventually more and more of this stuff can go to cpu-independent files. 26 1.1 christos Keep that in mind. */ 27 1.1 christos 28 1.1 christos #include "sysdep.h" 29 1.1 christos #include <stdio.h> 30 1.1 christos #include "ansidecl.h" 31 1.1 christos #include "dis-asm.h" 32 1.1 christos #include "bfd.h" 33 1.1 christos #include "symcat.h" 34 1.1 christos #include "m32r-desc.h" 35 1.1 christos #include "m32r-opc.h" 36 1.1 christos #include "cgen/basic-modes.h" 37 1.1 christos #include "opintl.h" 38 1.1 christos #include "safe-ctype.h" 39 1.1 christos 40 1.1 christos #undef min 41 1.1 christos #define min(a,b) ((a) < (b) ? (a) : (b)) 42 1.1 christos #undef max 43 1.1 christos #define max(a,b) ((a) > (b) ? (a) : (b)) 44 1.1 christos 45 1.1 christos /* Used by the ifield rtx function. */ 46 1.1 christos #define FLD(f) (fields->f) 47 1.1 christos 48 1.1 christos static const char * insert_normal 49 1.1 christos (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int, 50 1.1 christos unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR); 51 1.1 christos static const char * insert_insn_normal 52 1.1 christos (CGEN_CPU_DESC, const CGEN_INSN *, 53 1.1 christos CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma); 54 1.1 christos static int extract_normal 55 1.1 christos (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, 56 1.1 christos unsigned int, unsigned int, unsigned int, unsigned int, 57 1.1 christos unsigned int, unsigned int, bfd_vma, long *); 58 1.1 christos static int extract_insn_normal 59 1.1 christos (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *, 60 1.1 christos CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma); 61 1.1 christos #if CGEN_INT_INSN_P 62 1.1 christos static void put_insn_int_value 63 1.1 christos (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT); 64 1.1 christos #endif 65 1.1 christos #if ! CGEN_INT_INSN_P 66 1.1 christos static CGEN_INLINE void insert_1 67 1.1 christos (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *); 68 1.1 christos static CGEN_INLINE int fill_cache 69 1.1 christos (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma); 70 1.1 christos static CGEN_INLINE long extract_1 71 1.1 christos (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma); 72 1.1 christos #endif 73 1.1 christos 74 1.1 christos /* Operand insertion. */ 76 1.1 christos 77 1.1 christos #if ! CGEN_INT_INSN_P 78 1.1 christos 79 1.1 christos /* Subroutine of insert_normal. */ 80 1.1 christos 81 1.1 christos static CGEN_INLINE void 82 1.1 christos insert_1 (CGEN_CPU_DESC cd, 83 1.1 christos unsigned long value, 84 1.1 christos int start, 85 1.1 christos int length, 86 1.1 christos int word_length, 87 1.1 christos unsigned char *bufp) 88 1.1.1.6 christos { 89 1.1 christos unsigned long x, mask; 90 1.1 christos int shift; 91 1.1.1.6 christos 92 1.1 christos x = cgen_get_insn_value (cd, bufp, word_length, cd->endian); 93 1.1 christos 94 1.1.1.6 christos /* Written this way to avoid undefined behaviour. */ 95 1.1 christos mask = (1UL << (length - 1) << 1) - 1; 96 1.1 christos if (CGEN_INSN_LSB0_P) 97 1.1 christos shift = (start + 1) - length; 98 1.1 christos else 99 1.1 christos shift = (word_length - (start + length)); 100 1.1 christos x = (x & ~(mask << shift)) | ((value & mask) << shift); 101 1.1.1.6 christos 102 1.1 christos cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x, cd->endian); 103 1.1 christos } 104 1.1 christos 105 1.1 christos #endif /* ! CGEN_INT_INSN_P */ 106 1.1 christos 107 1.1 christos /* Default insertion routine. 108 1.1 christos 109 1.1 christos ATTRS is a mask of the boolean attributes. 110 1.1 christos WORD_OFFSET is the offset in bits from the start of the insn of the value. 111 1.1 christos WORD_LENGTH is the length of the word in bits in which the value resides. 112 1.1 christos START is the starting bit number in the word, architecture origin. 113 1.1 christos LENGTH is the length of VALUE in bits. 114 1.1 christos TOTAL_LENGTH is the total length of the insn in bits. 115 1.1 christos 116 1.1 christos The result is an error message or NULL if success. */ 117 1.1 christos 118 1.1 christos /* ??? This duplicates functionality with bfd's howto table and 119 1.1 christos bfd_install_relocation. */ 120 1.1 christos /* ??? This doesn't handle bfd_vma's. Create another function when 121 1.1 christos necessary. */ 122 1.1 christos 123 1.1 christos static const char * 124 1.1 christos insert_normal (CGEN_CPU_DESC cd, 125 1.1 christos long value, 126 1.1 christos unsigned int attrs, 127 1.1 christos unsigned int word_offset, 128 1.1 christos unsigned int start, 129 1.1 christos unsigned int length, 130 1.1 christos unsigned int word_length, 131 1.1 christos unsigned int total_length, 132 1.1 christos CGEN_INSN_BYTES_PTR buffer) 133 1.1 christos { 134 1.1.1.6 christos static char errbuf[100]; 135 1.1 christos unsigned long mask; 136 1.1 christos 137 1.1 christos /* If LENGTH is zero, this operand doesn't contribute to the value. */ 138 1.1 christos if (length == 0) 139 1.1 christos return NULL; 140 1.1.1.6 christos 141 1.1.1.6 christos /* Written this way to avoid undefined behaviour. */ 142 1.1.1.6 christos mask = (1UL << (length - 1) << 1) - 1; 143 1.1 christos 144 1.1 christos if (word_length > 8 * sizeof (CGEN_INSN_INT)) 145 1.1 christos abort (); 146 1.1 christos 147 1.1 christos /* For architectures with insns smaller than the base-insn-bitsize, 148 1.1 christos word_length may be too big. */ 149 1.1 christos if (cd->min_insn_bitsize < cd->base_insn_bitsize) 150 1.1 christos { 151 1.1 christos if (word_offset == 0 152 1.1 christos && word_length > total_length) 153 1.1 christos word_length = total_length; 154 1.1 christos } 155 1.1 christos 156 1.1 christos /* Ensure VALUE will fit. */ 157 1.1 christos if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT)) 158 1.1.1.6 christos { 159 1.1 christos long minval = - (1UL << (length - 1)); 160 1.1.1.3 christos unsigned long maxval = mask; 161 1.1 christos 162 1.1 christos if ((value > 0 && (unsigned long) value > maxval) 163 1.1 christos || value < minval) 164 1.1 christos { 165 1.1 christos /* xgettext:c-format */ 166 1.1 christos sprintf (errbuf, 167 1.1 christos _("operand out of range (%ld not between %ld and %lu)"), 168 1.1 christos value, minval, maxval); 169 1.1 christos return errbuf; 170 1.1 christos } 171 1.1 christos } 172 1.1 christos else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)) 173 1.1 christos { 174 1.1 christos unsigned long maxval = mask; 175 1.1 christos unsigned long val = (unsigned long) value; 176 1.1 christos 177 1.1 christos /* For hosts with a word size > 32 check to see if value has been sign 178 1.1 christos extended beyond 32 bits. If so then ignore these higher sign bits 179 1.1 christos as the user is attempting to store a 32-bit signed value into an 180 1.1 christos unsigned 32-bit field which is allowed. */ 181 1.1 christos if (sizeof (unsigned long) > 4 && ((value >> 32) == -1)) 182 1.1 christos val &= 0xFFFFFFFF; 183 1.1 christos 184 1.1 christos if (val > maxval) 185 1.1 christos { 186 1.1 christos /* xgettext:c-format */ 187 1.1 christos sprintf (errbuf, 188 1.1 christos _("operand out of range (0x%lx not between 0 and 0x%lx)"), 189 1.1 christos val, maxval); 190 1.1 christos return errbuf; 191 1.1 christos } 192 1.1 christos } 193 1.1 christos else 194 1.1 christos { 195 1.1 christos if (! cgen_signed_overflow_ok_p (cd)) 196 1.1.1.6 christos { 197 1.1.1.6 christos long minval = - (1UL << (length - 1)); 198 1.1.1.3 christos long maxval = (1UL << (length - 1)) - 1; 199 1.1 christos 200 1.1 christos if (value < minval || value > maxval) 201 1.1 christos { 202 1.1 christos sprintf 203 1.1 christos /* xgettext:c-format */ 204 1.1 christos (errbuf, _("operand out of range (%ld not between %ld and %ld)"), 205 1.1 christos value, minval, maxval); 206 1.1 christos return errbuf; 207 1.1 christos } 208 1.1 christos } 209 1.1 christos } 210 1.1 christos 211 1.1 christos #if CGEN_INT_INSN_P 212 1.1 christos 213 1.1.1.3 christos { 214 1.1 christos int shift_within_word, shift_to_word, shift; 215 1.1.1.3 christos 216 1.1.1.3 christos /* How to shift the value to BIT0 of the word. */ 217 1.1.1.3 christos shift_to_word = total_length - (word_offset + word_length); 218 1.1.1.3 christos 219 1.1 christos /* How to shift the value to the field within the word. */ 220 1.1.1.3 christos if (CGEN_INSN_LSB0_P) 221 1.1 christos shift_within_word = start + 1 - length; 222 1.1.1.3 christos else 223 1.1.1.3 christos shift_within_word = word_length - start - length; 224 1.1.1.3 christos 225 1.1.1.3 christos /* The total SHIFT, then mask in the value. */ 226 1.1 christos shift = shift_to_word + shift_within_word; 227 1.1 christos *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift); 228 1.1 christos } 229 1.1 christos 230 1.1 christos #else /* ! CGEN_INT_INSN_P */ 231 1.1 christos 232 1.1 christos { 233 1.1 christos unsigned char *bufp = (unsigned char *) buffer + word_offset / 8; 234 1.1 christos 235 1.1 christos insert_1 (cd, value, start, length, word_length, bufp); 236 1.1 christos } 237 1.1 christos 238 1.1 christos #endif /* ! CGEN_INT_INSN_P */ 239 1.1 christos 240 1.1 christos return NULL; 241 1.1 christos } 242 1.1 christos 243 1.1 christos /* Default insn builder (insert handler). 244 1.1 christos The instruction is recorded in CGEN_INT_INSN_P byte order (meaning 245 1.1 christos that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is 246 1.1 christos recorded in host byte order, otherwise BUFFER is an array of bytes 247 1.1 christos and the value is recorded in target byte order). 248 1.1 christos The result is an error message or NULL if success. */ 249 1.1 christos 250 1.1 christos static const char * 251 1.1 christos insert_insn_normal (CGEN_CPU_DESC cd, 252 1.1 christos const CGEN_INSN * insn, 253 1.1 christos CGEN_FIELDS * fields, 254 1.1 christos CGEN_INSN_BYTES_PTR buffer, 255 1.1 christos bfd_vma pc) 256 1.1 christos { 257 1.1 christos const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); 258 1.1 christos unsigned long value; 259 1.1 christos const CGEN_SYNTAX_CHAR_TYPE * syn; 260 1.1 christos 261 1.1 christos CGEN_INIT_INSERT (cd); 262 1.1 christos value = CGEN_INSN_BASE_VALUE (insn); 263 1.1 christos 264 1.1 christos /* If we're recording insns as numbers (rather than a string of bytes), 265 1.1 christos target byte order handling is deferred until later. */ 266 1.1 christos 267 1.1 christos #if CGEN_INT_INSN_P 268 1.1 christos 269 1.1 christos put_insn_int_value (cd, buffer, cd->base_insn_bitsize, 270 1.1 christos CGEN_FIELDS_BITSIZE (fields), value); 271 1.1 christos 272 1.1 christos #else 273 1.1 christos 274 1.1.1.6 christos cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize, 275 1.1.1.6 christos (unsigned) CGEN_FIELDS_BITSIZE (fields)), 276 1.1 christos value, cd->insn_endian); 277 1.1 christos 278 1.1 christos #endif /* ! CGEN_INT_INSN_P */ 279 1.1 christos 280 1.1 christos /* ??? It would be better to scan the format's fields. 281 1.1 christos Still need to be able to insert a value based on the operand though; 282 1.1 christos e.g. storing a branch displacement that got resolved later. 283 1.1 christos Needs more thought first. */ 284 1.1 christos 285 1.1 christos for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn) 286 1.1 christos { 287 1.1 christos const char *errmsg; 288 1.1 christos 289 1.1 christos if (CGEN_SYNTAX_CHAR_P (* syn)) 290 1.1 christos continue; 291 1.1 christos 292 1.1 christos errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn), 293 1.1 christos fields, buffer, pc); 294 1.1 christos if (errmsg) 295 1.1 christos return errmsg; 296 1.1 christos } 297 1.1 christos 298 1.1 christos return NULL; 299 1.1 christos } 300 1.1 christos 301 1.1 christos #if CGEN_INT_INSN_P 302 1.1 christos /* Cover function to store an insn value into an integral insn. Must go here 303 1.1 christos because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */ 304 1.1 christos 305 1.1 christos static void 306 1.1 christos put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 307 1.1 christos CGEN_INSN_BYTES_PTR buf, 308 1.1 christos int length, 309 1.1 christos int insn_length, 310 1.1 christos CGEN_INSN_INT value) 311 1.1 christos { 312 1.1 christos /* For architectures with insns smaller than the base-insn-bitsize, 313 1.1 christos length may be too big. */ 314 1.1 christos if (length > insn_length) 315 1.1 christos *buf = value; 316 1.1 christos else 317 1.1 christos { 318 1.1 christos int shift = insn_length - length; 319 1.1.1.6 christos /* Written this way to avoid undefined behaviour. */ 320 1.1 christos CGEN_INSN_INT mask = length == 0 ? 0 : (1UL << (length - 1) << 1) - 1; 321 1.1 christos 322 1.1 christos *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift); 323 1.1 christos } 324 1.1 christos } 325 1.1 christos #endif 326 1.1 christos 327 1.1 christos /* Operand extraction. */ 329 1.1 christos 330 1.1 christos #if ! CGEN_INT_INSN_P 331 1.1 christos 332 1.1 christos /* Subroutine of extract_normal. 333 1.1 christos Ensure sufficient bytes are cached in EX_INFO. 334 1.1 christos OFFSET is the offset in bytes from the start of the insn of the value. 335 1.1 christos BYTES is the length of the needed value. 336 1.1 christos Returns 1 for success, 0 for failure. */ 337 1.1 christos 338 1.1 christos static CGEN_INLINE int 339 1.1 christos fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 340 1.1 christos CGEN_EXTRACT_INFO *ex_info, 341 1.1 christos int offset, 342 1.1 christos int bytes, 343 1.1 christos bfd_vma pc) 344 1.1 christos { 345 1.1 christos /* It's doubtful that the middle part has already been fetched so 346 1.1 christos we don't optimize that case. kiss. */ 347 1.1 christos unsigned int mask; 348 1.1 christos disassemble_info *info = (disassemble_info *) ex_info->dis_info; 349 1.1 christos 350 1.1 christos /* First do a quick check. */ 351 1.1 christos mask = (1 << bytes) - 1; 352 1.1 christos if (((ex_info->valid >> offset) & mask) == mask) 353 1.1 christos return 1; 354 1.1 christos 355 1.1 christos /* Search for the first byte we need to read. */ 356 1.1 christos for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1) 357 1.1 christos if (! (mask & ex_info->valid)) 358 1.1 christos break; 359 1.1 christos 360 1.1 christos if (bytes) 361 1.1 christos { 362 1.1 christos int status; 363 1.1 christos 364 1.1 christos pc += offset; 365 1.1 christos status = (*info->read_memory_func) 366 1.1 christos (pc, ex_info->insn_bytes + offset, bytes, info); 367 1.1 christos 368 1.1 christos if (status != 0) 369 1.1 christos { 370 1.1 christos (*info->memory_error_func) (status, pc, info); 371 1.1 christos return 0; 372 1.1 christos } 373 1.1 christos 374 1.1 christos ex_info->valid |= ((1 << bytes) - 1) << offset; 375 1.1 christos } 376 1.1 christos 377 1.1 christos return 1; 378 1.1 christos } 379 1.1 christos 380 1.1 christos /* Subroutine of extract_normal. */ 381 1.1 christos 382 1.1 christos static CGEN_INLINE long 383 1.1 christos extract_1 (CGEN_CPU_DESC cd, 384 1.1 christos CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED, 385 1.1 christos int start, 386 1.1 christos int length, 387 1.1 christos int word_length, 388 1.1 christos unsigned char *bufp, 389 1.1 christos bfd_vma pc ATTRIBUTE_UNUSED) 390 1.1 christos { 391 1.1 christos unsigned long x; 392 1.1.1.6 christos int shift; 393 1.1 christos 394 1.1 christos x = cgen_get_insn_value (cd, bufp, word_length, cd->endian); 395 1.1 christos 396 1.1 christos if (CGEN_INSN_LSB0_P) 397 1.1 christos shift = (start + 1) - length; 398 1.1 christos else 399 1.1 christos shift = (word_length - (start + length)); 400 1.1 christos return x >> shift; 401 1.1 christos } 402 1.1 christos 403 1.1 christos #endif /* ! CGEN_INT_INSN_P */ 404 1.1 christos 405 1.1 christos /* Default extraction routine. 406 1.1 christos 407 1.1 christos INSN_VALUE is the first base_insn_bitsize bits of the insn in host order, 408 1.1 christos or sometimes less for cases like the m32r where the base insn size is 32 409 1.1 christos but some insns are 16 bits. 410 1.1 christos ATTRS is a mask of the boolean attributes. We only need `SIGNED', 411 1.1 christos but for generality we take a bitmask of all of them. 412 1.1 christos WORD_OFFSET is the offset in bits from the start of the insn of the value. 413 1.1 christos WORD_LENGTH is the length of the word in bits in which the value resides. 414 1.1 christos START is the starting bit number in the word, architecture origin. 415 1.1 christos LENGTH is the length of VALUE in bits. 416 1.1 christos TOTAL_LENGTH is the total length of the insn in bits. 417 1.1 christos 418 1.1 christos Returns 1 for success, 0 for failure. */ 419 1.1 christos 420 1.1 christos /* ??? The return code isn't properly used. wip. */ 421 1.1 christos 422 1.1 christos /* ??? This doesn't handle bfd_vma's. Create another function when 423 1.1 christos necessary. */ 424 1.1 christos 425 1.1 christos static int 426 1.1 christos extract_normal (CGEN_CPU_DESC cd, 427 1.1 christos #if ! CGEN_INT_INSN_P 428 1.1 christos CGEN_EXTRACT_INFO *ex_info, 429 1.1 christos #else 430 1.1 christos CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED, 431 1.1 christos #endif 432 1.1 christos CGEN_INSN_INT insn_value, 433 1.1 christos unsigned int attrs, 434 1.1 christos unsigned int word_offset, 435 1.1 christos unsigned int start, 436 1.1 christos unsigned int length, 437 1.1 christos unsigned int word_length, 438 1.1 christos unsigned int total_length, 439 1.1 christos #if ! CGEN_INT_INSN_P 440 1.1 christos bfd_vma pc, 441 1.1 christos #else 442 1.1 christos bfd_vma pc ATTRIBUTE_UNUSED, 443 1.1 christos #endif 444 1.1 christos long *valuep) 445 1.1 christos { 446 1.1 christos long value, mask; 447 1.1 christos 448 1.1 christos /* If LENGTH is zero, this operand doesn't contribute to the value 449 1.1 christos so give it a standard value of zero. */ 450 1.1 christos if (length == 0) 451 1.1 christos { 452 1.1 christos *valuep = 0; 453 1.1 christos return 1; 454 1.1 christos } 455 1.1 christos 456 1.1 christos if (word_length > 8 * sizeof (CGEN_INSN_INT)) 457 1.1 christos abort (); 458 1.1 christos 459 1.1 christos /* For architectures with insns smaller than the insn-base-bitsize, 460 1.1 christos word_length may be too big. */ 461 1.1 christos if (cd->min_insn_bitsize < cd->base_insn_bitsize) 462 1.1 christos { 463 1.1 christos if (word_offset + word_length > total_length) 464 1.1 christos word_length = total_length - word_offset; 465 1.1 christos } 466 1.1 christos 467 1.1 christos /* Does the value reside in INSN_VALUE, and at the right alignment? */ 468 1.1 christos 469 1.1 christos if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length)) 470 1.1 christos { 471 1.1 christos if (CGEN_INSN_LSB0_P) 472 1.1 christos value = insn_value >> ((word_offset + start + 1) - length); 473 1.1 christos else 474 1.1 christos value = insn_value >> (total_length - ( word_offset + start + length)); 475 1.1 christos } 476 1.1 christos 477 1.1 christos #if ! CGEN_INT_INSN_P 478 1.1 christos 479 1.1 christos else 480 1.1 christos { 481 1.1 christos unsigned char *bufp = ex_info->insn_bytes + word_offset / 8; 482 1.1 christos 483 1.1 christos if (word_length > 8 * sizeof (CGEN_INSN_INT)) 484 1.1 christos abort (); 485 1.1.1.6 christos 486 1.1.1.6 christos if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0) 487 1.1.1.6 christos { 488 1.1.1.6 christos *valuep = 0; 489 1.1 christos return 0; 490 1.1 christos } 491 1.1 christos 492 1.1 christos value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc); 493 1.1 christos } 494 1.1 christos 495 1.1 christos #endif /* ! CGEN_INT_INSN_P */ 496 1.1.1.6 christos 497 1.1 christos /* Written this way to avoid undefined behaviour. */ 498 1.1 christos mask = (1UL << (length - 1) << 1) - 1; 499 1.1 christos 500 1.1 christos value &= mask; 501 1.1.1.6 christos /* sign extend? */ 502 1.1 christos if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED) 503 1.1 christos && (value & (1UL << (length - 1)))) 504 1.1 christos value |= ~mask; 505 1.1 christos 506 1.1 christos *valuep = value; 507 1.1 christos 508 1.1 christos return 1; 509 1.1 christos } 510 1.1 christos 511 1.1 christos /* Default insn extractor. 512 1.1 christos 513 1.1 christos INSN_VALUE is the first base_insn_bitsize bits, translated to host order. 514 1.1 christos The extracted fields are stored in FIELDS. 515 1.1 christos EX_INFO is used to handle reading variable length insns. 516 1.1 christos Return the length of the insn in bits, or 0 if no match, 517 1.1 christos or -1 if an error occurs fetching data (memory_error_func will have 518 1.1 christos been called). */ 519 1.1 christos 520 1.1 christos static int 521 1.1 christos extract_insn_normal (CGEN_CPU_DESC cd, 522 1.1 christos const CGEN_INSN *insn, 523 1.1 christos CGEN_EXTRACT_INFO *ex_info, 524 1.1 christos CGEN_INSN_INT insn_value, 525 1.1 christos CGEN_FIELDS *fields, 526 1.1 christos bfd_vma pc) 527 1.1 christos { 528 1.1 christos const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); 529 1.1 christos const CGEN_SYNTAX_CHAR_TYPE *syn; 530 1.1 christos 531 1.1 christos CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); 532 1.1 christos 533 1.1 christos CGEN_INIT_EXTRACT (cd); 534 1.1 christos 535 1.1 christos for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn) 536 1.1 christos { 537 1.1 christos int length; 538 1.1 christos 539 1.1 christos if (CGEN_SYNTAX_CHAR_P (*syn)) 540 1.1 christos continue; 541 1.1 christos 542 1.1 christos length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn), 543 1.1 christos ex_info, insn_value, fields, pc); 544 1.1 christos if (length <= 0) 545 1.1 christos return length; 546 1.1 christos } 547 1.1 christos 548 1.1 christos /* We recognized and successfully extracted this insn. */ 549 1.1 christos return CGEN_INSN_BITSIZE (insn); 550 1.1 christos } 551 1.1 christos 552 1.1 christos /* Machine generated code added here. */ 554 1.1 christos 555 1.1 christos const char * m32r_cgen_insert_operand 556 1.1 christos (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma); 557 1.1 christos 558 1.1 christos /* Main entry point for operand insertion. 559 1.1 christos 560 1.1 christos This function is basically just a big switch statement. Earlier versions 561 1.1 christos used tables to look up the function to use, but 562 1.1 christos - if the table contains both assembler and disassembler functions then 563 1.1 christos the disassembler contains much of the assembler and vice-versa, 564 1.1 christos - there's a lot of inlining possibilities as things grow, 565 1.1 christos - using a switch statement avoids the function call overhead. 566 1.1 christos 567 1.1 christos This function could be moved into `parse_insn_normal', but keeping it 568 1.1 christos separate makes clear the interface between `parse_insn_normal' and each of 569 1.1 christos the handlers. It's also needed by GAS to insert operands that couldn't be 570 1.1 christos resolved during parsing. */ 571 1.1 christos 572 1.1 christos const char * 573 1.1 christos m32r_cgen_insert_operand (CGEN_CPU_DESC cd, 574 1.1 christos int opindex, 575 1.1 christos CGEN_FIELDS * fields, 576 1.1 christos CGEN_INSN_BYTES_PTR buffer, 577 1.1 christos bfd_vma pc ATTRIBUTE_UNUSED) 578 1.1 christos { 579 1.1 christos const char * errmsg = NULL; 580 1.1 christos unsigned int total_length = CGEN_FIELDS_BITSIZE (fields); 581 1.1 christos 582 1.1 christos switch (opindex) 583 1.1 christos { 584 1.1 christos case M32R_OPERAND_ACC : 585 1.1 christos errmsg = insert_normal (cd, fields->f_acc, 0, 0, 8, 1, 32, total_length, buffer); 586 1.1 christos break; 587 1.1 christos case M32R_OPERAND_ACCD : 588 1.1 christos errmsg = insert_normal (cd, fields->f_accd, 0, 0, 4, 2, 32, total_length, buffer); 589 1.1 christos break; 590 1.1 christos case M32R_OPERAND_ACCS : 591 1.1 christos errmsg = insert_normal (cd, fields->f_accs, 0, 0, 12, 2, 32, total_length, buffer); 592 1.1 christos break; 593 1.1 christos case M32R_OPERAND_DCR : 594 1.1 christos errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer); 595 1.1 christos break; 596 1.1 christos case M32R_OPERAND_DISP16 : 597 1.1 christos { 598 1.1 christos long value = fields->f_disp16; 599 1.1 christos value = ((SI) (((value) - (pc))) >> (2)); 600 1.1 christos errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 16, 16, 32, total_length, buffer); 601 1.1 christos } 602 1.1 christos break; 603 1.1 christos case M32R_OPERAND_DISP24 : 604 1.1 christos { 605 1.1 christos long value = fields->f_disp24; 606 1.1 christos value = ((SI) (((value) - (pc))) >> (2)); 607 1.1 christos errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 24, 32, total_length, buffer); 608 1.1 christos } 609 1.1 christos break; 610 1.1 christos case M32R_OPERAND_DISP8 : 611 1.1 christos { 612 1.1 christos long value = fields->f_disp8; 613 1.1 christos value = ((SI) (((value) - (((pc) & (-4))))) >> (2)); 614 1.1 christos errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, buffer); 615 1.1 christos } 616 1.1 christos break; 617 1.1 christos case M32R_OPERAND_DR : 618 1.1 christos errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer); 619 1.1 christos break; 620 1.1 christos case M32R_OPERAND_HASH : 621 1.1 christos break; 622 1.1 christos case M32R_OPERAND_HI16 : 623 1.1 christos errmsg = insert_normal (cd, fields->f_hi16, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, buffer); 624 1.1 christos break; 625 1.1 christos case M32R_OPERAND_IMM1 : 626 1.1 christos { 627 1.1 christos long value = fields->f_imm1; 628 1.1 christos value = ((value) - (1)); 629 1.1 christos errmsg = insert_normal (cd, value, 0, 0, 15, 1, 32, total_length, buffer); 630 1.1 christos } 631 1.1 christos break; 632 1.1 christos case M32R_OPERAND_SCR : 633 1.1 christos errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer); 634 1.1 christos break; 635 1.1 christos case M32R_OPERAND_SIMM16 : 636 1.1 christos errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer); 637 1.1 christos break; 638 1.1 christos case M32R_OPERAND_SIMM8 : 639 1.1 christos errmsg = insert_normal (cd, fields->f_simm8, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, buffer); 640 1.1 christos break; 641 1.1 christos case M32R_OPERAND_SLO16 : 642 1.1 christos errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer); 643 1.1 christos break; 644 1.1 christos case M32R_OPERAND_SR : 645 1.1 christos errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer); 646 1.1 christos break; 647 1.1 christos case M32R_OPERAND_SRC1 : 648 1.1 christos errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer); 649 1.1 christos break; 650 1.1 christos case M32R_OPERAND_SRC2 : 651 1.1 christos errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer); 652 1.1 christos break; 653 1.1 christos case M32R_OPERAND_UIMM16 : 654 1.1 christos errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer); 655 1.1 christos break; 656 1.1 christos case M32R_OPERAND_UIMM24 : 657 1.1 christos errmsg = insert_normal (cd, fields->f_uimm24, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 24, 32, total_length, buffer); 658 1.1 christos break; 659 1.1 christos case M32R_OPERAND_UIMM3 : 660 1.1 christos errmsg = insert_normal (cd, fields->f_uimm3, 0, 0, 5, 3, 32, total_length, buffer); 661 1.1 christos break; 662 1.1 christos case M32R_OPERAND_UIMM4 : 663 1.1 christos errmsg = insert_normal (cd, fields->f_uimm4, 0, 0, 12, 4, 32, total_length, buffer); 664 1.1 christos break; 665 1.1 christos case M32R_OPERAND_UIMM5 : 666 1.1 christos errmsg = insert_normal (cd, fields->f_uimm5, 0, 0, 11, 5, 32, total_length, buffer); 667 1.1 christos break; 668 1.1 christos case M32R_OPERAND_UIMM8 : 669 1.1 christos errmsg = insert_normal (cd, fields->f_uimm8, 0, 0, 8, 8, 32, total_length, buffer); 670 1.1 christos break; 671 1.1 christos case M32R_OPERAND_ULO16 : 672 1.1 christos errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer); 673 1.1 christos break; 674 1.1.1.5 christos 675 1.1.1.5 christos default : 676 1.1.1.5 christos /* xgettext:c-format */ 677 1.1 christos opcodes_error_handler 678 1.1 christos (_("internal error: unrecognized field %d while building insn"), 679 1.1 christos opindex); 680 1.1 christos abort (); 681 1.1 christos } 682 1.1 christos 683 1.1 christos return errmsg; 684 1.1 christos } 685 1.1 christos 686 1.1 christos int m32r_cgen_extract_operand 687 1.1 christos (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma); 688 1.1 christos 689 1.1 christos /* Main entry point for operand extraction. 690 1.1 christos The result is <= 0 for error, >0 for success. 691 1.1 christos ??? Actual values aren't well defined right now. 692 1.1 christos 693 1.1 christos This function is basically just a big switch statement. Earlier versions 694 1.1 christos used tables to look up the function to use, but 695 1.1 christos - if the table contains both assembler and disassembler functions then 696 1.1 christos the disassembler contains much of the assembler and vice-versa, 697 1.1 christos - there's a lot of inlining possibilities as things grow, 698 1.1 christos - using a switch statement avoids the function call overhead. 699 1.1 christos 700 1.1 christos This function could be moved into `print_insn_normal', but keeping it 701 1.1 christos separate makes clear the interface between `print_insn_normal' and each of 702 1.1 christos the handlers. */ 703 1.1 christos 704 1.1 christos int 705 1.1 christos m32r_cgen_extract_operand (CGEN_CPU_DESC cd, 706 1.1 christos int opindex, 707 1.1 christos CGEN_EXTRACT_INFO *ex_info, 708 1.1 christos CGEN_INSN_INT insn_value, 709 1.1 christos CGEN_FIELDS * fields, 710 1.1 christos bfd_vma pc) 711 1.1 christos { 712 1.1 christos /* Assume success (for those operands that are nops). */ 713 1.1 christos int length = 1; 714 1.1 christos unsigned int total_length = CGEN_FIELDS_BITSIZE (fields); 715 1.1 christos 716 1.1 christos switch (opindex) 717 1.1 christos { 718 1.1 christos case M32R_OPERAND_ACC : 719 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 1, 32, total_length, pc, & fields->f_acc); 720 1.1 christos break; 721 1.1 christos case M32R_OPERAND_ACCD : 722 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 2, 32, total_length, pc, & fields->f_accd); 723 1.1 christos break; 724 1.1 christos case M32R_OPERAND_ACCS : 725 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 2, 32, total_length, pc, & fields->f_accs); 726 1.1 christos break; 727 1.1 christos case M32R_OPERAND_DCR : 728 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1); 729 1.1 christos break; 730 1.1 christos case M32R_OPERAND_DISP16 : 731 1.1.1.6 christos { 732 1.1 christos long value; 733 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 16, 16, 32, total_length, pc, & value); 734 1.1 christos value = ((((value) * (4))) + (pc)); 735 1.1 christos fields->f_disp16 = value; 736 1.1 christos } 737 1.1 christos break; 738 1.1 christos case M32R_OPERAND_DISP24 : 739 1.1.1.6 christos { 740 1.1 christos long value; 741 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 24, 32, total_length, pc, & value); 742 1.1 christos value = ((((value) * (4))) + (pc)); 743 1.1 christos fields->f_disp24 = value; 744 1.1 christos } 745 1.1 christos break; 746 1.1 christos case M32R_OPERAND_DISP8 : 747 1.1.1.6 christos { 748 1.1 christos long value; 749 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, pc, & value); 750 1.1 christos value = ((((value) * (4))) + (((pc) & (-4)))); 751 1.1 christos fields->f_disp8 = value; 752 1.1 christos } 753 1.1 christos break; 754 1.1 christos case M32R_OPERAND_DR : 755 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1); 756 1.1 christos break; 757 1.1 christos case M32R_OPERAND_HASH : 758 1.1 christos break; 759 1.1 christos case M32R_OPERAND_HI16 : 760 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, pc, & fields->f_hi16); 761 1.1 christos break; 762 1.1 christos case M32R_OPERAND_IMM1 : 763 1.1 christos { 764 1.1 christos long value; 765 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & value); 766 1.1 christos value = ((value) + (1)); 767 1.1 christos fields->f_imm1 = value; 768 1.1 christos } 769 1.1 christos break; 770 1.1 christos case M32R_OPERAND_SCR : 771 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2); 772 1.1 christos break; 773 1.1 christos case M32R_OPERAND_SIMM16 : 774 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16); 775 1.1 christos break; 776 1.1 christos case M32R_OPERAND_SIMM8 : 777 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, pc, & fields->f_simm8); 778 1.1 christos break; 779 1.1 christos case M32R_OPERAND_SLO16 : 780 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16); 781 1.1 christos break; 782 1.1 christos case M32R_OPERAND_SR : 783 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2); 784 1.1 christos break; 785 1.1 christos case M32R_OPERAND_SRC1 : 786 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1); 787 1.1 christos break; 788 1.1 christos case M32R_OPERAND_SRC2 : 789 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2); 790 1.1 christos break; 791 1.1 christos case M32R_OPERAND_UIMM16 : 792 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16); 793 1.1 christos break; 794 1.1 christos case M32R_OPERAND_UIMM24 : 795 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 24, 32, total_length, pc, & fields->f_uimm24); 796 1.1 christos break; 797 1.1 christos case M32R_OPERAND_UIMM3 : 798 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_uimm3); 799 1.1 christos break; 800 1.1 christos case M32R_OPERAND_UIMM4 : 801 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_uimm4); 802 1.1 christos break; 803 1.1 christos case M32R_OPERAND_UIMM5 : 804 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 5, 32, total_length, pc, & fields->f_uimm5); 805 1.1 christos break; 806 1.1 christos case M32R_OPERAND_UIMM8 : 807 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 32, total_length, pc, & fields->f_uimm8); 808 1.1 christos break; 809 1.1 christos case M32R_OPERAND_ULO16 : 810 1.1 christos length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16); 811 1.1 christos break; 812 1.1.1.5 christos 813 1.1.1.5 christos default : 814 1.1.1.5 christos /* xgettext:c-format */ 815 1.1 christos opcodes_error_handler 816 1.1 christos (_("internal error: unrecognized field %d while decoding insn"), 817 1.1 christos opindex); 818 1.1 christos abort (); 819 1.1 christos } 820 1.1 christos 821 1.1.1.3 christos return length; 822 1.1 christos } 823 1.1 christos 824 1.1 christos cgen_insert_fn * const m32r_cgen_insert_handlers[] = 825 1.1 christos { 826 1.1.1.3 christos insert_insn_normal, 827 1.1 christos }; 828 1.1 christos 829 1.1 christos cgen_extract_fn * const m32r_cgen_extract_handlers[] = 830 1.1 christos { 831 1.1 christos extract_insn_normal, 832 1.1 christos }; 833 1.1 christos 834 1.1 christos int m32r_cgen_get_int_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *); 835 1.1 christos bfd_vma m32r_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *); 836 1.1 christos 837 1.1 christos /* Getting values from cgen_fields is handled by a collection of functions. 838 1.1 christos They are distinguished by the type of the VALUE argument they return. 839 1.1 christos TODO: floating point, inlining support, remove cases where result type 840 1.1 christos not appropriate. */ 841 1.1 christos 842 1.1 christos int 843 1.1 christos m32r_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 844 1.1 christos int opindex, 845 1.1 christos const CGEN_FIELDS * fields) 846 1.1 christos { 847 1.1 christos int value; 848 1.1 christos 849 1.1 christos switch (opindex) 850 1.1 christos { 851 1.1 christos case M32R_OPERAND_ACC : 852 1.1 christos value = fields->f_acc; 853 1.1 christos break; 854 1.1 christos case M32R_OPERAND_ACCD : 855 1.1 christos value = fields->f_accd; 856 1.1 christos break; 857 1.1 christos case M32R_OPERAND_ACCS : 858 1.1 christos value = fields->f_accs; 859 1.1 christos break; 860 1.1 christos case M32R_OPERAND_DCR : 861 1.1 christos value = fields->f_r1; 862 1.1 christos break; 863 1.1 christos case M32R_OPERAND_DISP16 : 864 1.1 christos value = fields->f_disp16; 865 1.1 christos break; 866 1.1 christos case M32R_OPERAND_DISP24 : 867 1.1 christos value = fields->f_disp24; 868 1.1 christos break; 869 1.1 christos case M32R_OPERAND_DISP8 : 870 1.1 christos value = fields->f_disp8; 871 1.1 christos break; 872 1.1 christos case M32R_OPERAND_DR : 873 1.1 christos value = fields->f_r1; 874 1.1 christos break; 875 1.1 christos case M32R_OPERAND_HASH : 876 1.1 christos value = 0; 877 1.1 christos break; 878 1.1 christos case M32R_OPERAND_HI16 : 879 1.1 christos value = fields->f_hi16; 880 1.1 christos break; 881 1.1 christos case M32R_OPERAND_IMM1 : 882 1.1 christos value = fields->f_imm1; 883 1.1 christos break; 884 1.1 christos case M32R_OPERAND_SCR : 885 1.1 christos value = fields->f_r2; 886 1.1 christos break; 887 1.1 christos case M32R_OPERAND_SIMM16 : 888 1.1 christos value = fields->f_simm16; 889 1.1 christos break; 890 1.1 christos case M32R_OPERAND_SIMM8 : 891 1.1 christos value = fields->f_simm8; 892 1.1 christos break; 893 1.1 christos case M32R_OPERAND_SLO16 : 894 1.1 christos value = fields->f_simm16; 895 1.1 christos break; 896 1.1 christos case M32R_OPERAND_SR : 897 1.1 christos value = fields->f_r2; 898 1.1 christos break; 899 1.1 christos case M32R_OPERAND_SRC1 : 900 1.1 christos value = fields->f_r1; 901 1.1 christos break; 902 1.1 christos case M32R_OPERAND_SRC2 : 903 1.1 christos value = fields->f_r2; 904 1.1 christos break; 905 1.1 christos case M32R_OPERAND_UIMM16 : 906 1.1 christos value = fields->f_uimm16; 907 1.1 christos break; 908 1.1 christos case M32R_OPERAND_UIMM24 : 909 1.1 christos value = fields->f_uimm24; 910 1.1 christos break; 911 1.1 christos case M32R_OPERAND_UIMM3 : 912 1.1 christos value = fields->f_uimm3; 913 1.1 christos break; 914 1.1 christos case M32R_OPERAND_UIMM4 : 915 1.1 christos value = fields->f_uimm4; 916 1.1 christos break; 917 1.1 christos case M32R_OPERAND_UIMM5 : 918 1.1 christos value = fields->f_uimm5; 919 1.1 christos break; 920 1.1 christos case M32R_OPERAND_UIMM8 : 921 1.1 christos value = fields->f_uimm8; 922 1.1 christos break; 923 1.1 christos case M32R_OPERAND_ULO16 : 924 1.1 christos value = fields->f_uimm16; 925 1.1 christos break; 926 1.1.1.5 christos 927 1.1.1.5 christos default : 928 1.1.1.5 christos /* xgettext:c-format */ 929 1.1 christos opcodes_error_handler 930 1.1 christos (_("internal error: unrecognized field %d while getting int operand"), 931 1.1 christos opindex); 932 1.1 christos abort (); 933 1.1 christos } 934 1.1 christos 935 1.1 christos return value; 936 1.1 christos } 937 1.1 christos 938 1.1 christos bfd_vma 939 1.1 christos m32r_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 940 1.1 christos int opindex, 941 1.1 christos const CGEN_FIELDS * fields) 942 1.1 christos { 943 1.1 christos bfd_vma value; 944 1.1 christos 945 1.1 christos switch (opindex) 946 1.1 christos { 947 1.1 christos case M32R_OPERAND_ACC : 948 1.1 christos value = fields->f_acc; 949 1.1 christos break; 950 1.1 christos case M32R_OPERAND_ACCD : 951 1.1 christos value = fields->f_accd; 952 1.1 christos break; 953 1.1 christos case M32R_OPERAND_ACCS : 954 1.1 christos value = fields->f_accs; 955 1.1 christos break; 956 1.1 christos case M32R_OPERAND_DCR : 957 1.1 christos value = fields->f_r1; 958 1.1 christos break; 959 1.1 christos case M32R_OPERAND_DISP16 : 960 1.1 christos value = fields->f_disp16; 961 1.1 christos break; 962 1.1 christos case M32R_OPERAND_DISP24 : 963 1.1 christos value = fields->f_disp24; 964 1.1 christos break; 965 1.1 christos case M32R_OPERAND_DISP8 : 966 1.1 christos value = fields->f_disp8; 967 1.1 christos break; 968 1.1 christos case M32R_OPERAND_DR : 969 1.1 christos value = fields->f_r1; 970 1.1 christos break; 971 1.1 christos case M32R_OPERAND_HASH : 972 1.1 christos value = 0; 973 1.1 christos break; 974 1.1 christos case M32R_OPERAND_HI16 : 975 1.1 christos value = fields->f_hi16; 976 1.1 christos break; 977 1.1 christos case M32R_OPERAND_IMM1 : 978 1.1 christos value = fields->f_imm1; 979 1.1 christos break; 980 1.1 christos case M32R_OPERAND_SCR : 981 1.1 christos value = fields->f_r2; 982 1.1 christos break; 983 1.1 christos case M32R_OPERAND_SIMM16 : 984 1.1 christos value = fields->f_simm16; 985 1.1 christos break; 986 1.1 christos case M32R_OPERAND_SIMM8 : 987 1.1 christos value = fields->f_simm8; 988 1.1 christos break; 989 1.1 christos case M32R_OPERAND_SLO16 : 990 1.1 christos value = fields->f_simm16; 991 1.1 christos break; 992 1.1 christos case M32R_OPERAND_SR : 993 1.1 christos value = fields->f_r2; 994 1.1 christos break; 995 1.1 christos case M32R_OPERAND_SRC1 : 996 1.1 christos value = fields->f_r1; 997 1.1 christos break; 998 1.1 christos case M32R_OPERAND_SRC2 : 999 1.1 christos value = fields->f_r2; 1000 1.1 christos break; 1001 1.1 christos case M32R_OPERAND_UIMM16 : 1002 1.1 christos value = fields->f_uimm16; 1003 1.1 christos break; 1004 1.1 christos case M32R_OPERAND_UIMM24 : 1005 1.1 christos value = fields->f_uimm24; 1006 1.1 christos break; 1007 1.1 christos case M32R_OPERAND_UIMM3 : 1008 1.1 christos value = fields->f_uimm3; 1009 1.1 christos break; 1010 1.1 christos case M32R_OPERAND_UIMM4 : 1011 1.1 christos value = fields->f_uimm4; 1012 1.1 christos break; 1013 1.1 christos case M32R_OPERAND_UIMM5 : 1014 1.1 christos value = fields->f_uimm5; 1015 1.1 christos break; 1016 1.1 christos case M32R_OPERAND_UIMM8 : 1017 1.1 christos value = fields->f_uimm8; 1018 1.1 christos break; 1019 1.1 christos case M32R_OPERAND_ULO16 : 1020 1.1 christos value = fields->f_uimm16; 1021 1.1 christos break; 1022 1.1.1.5 christos 1023 1.1.1.5 christos default : 1024 1.1.1.5 christos /* xgettext:c-format */ 1025 1.1 christos opcodes_error_handler 1026 1.1 christos (_("internal error: unrecognized field %d while getting vma operand"), 1027 1.1 christos opindex); 1028 1.1 christos abort (); 1029 1.1 christos } 1030 1.1 christos 1031 1.1 christos return value; 1032 1.1 christos } 1033 1.1 christos 1034 1.1 christos void m32r_cgen_set_int_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, int); 1035 1.1 christos void m32r_cgen_set_vma_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma); 1036 1.1 christos 1037 1.1 christos /* Stuffing values in cgen_fields is handled by a collection of functions. 1038 1.1 christos They are distinguished by the type of the VALUE argument they accept. 1039 1.1 christos TODO: floating point, inlining support, remove cases where argument type 1040 1.1 christos not appropriate. */ 1041 1.1 christos 1042 1.1 christos void 1043 1.1 christos m32r_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 1044 1.1 christos int opindex, 1045 1.1 christos CGEN_FIELDS * fields, 1046 1.1 christos int value) 1047 1.1 christos { 1048 1.1 christos switch (opindex) 1049 1.1 christos { 1050 1.1 christos case M32R_OPERAND_ACC : 1051 1.1 christos fields->f_acc = value; 1052 1.1 christos break; 1053 1.1 christos case M32R_OPERAND_ACCD : 1054 1.1 christos fields->f_accd = value; 1055 1.1 christos break; 1056 1.1 christos case M32R_OPERAND_ACCS : 1057 1.1 christos fields->f_accs = value; 1058 1.1 christos break; 1059 1.1 christos case M32R_OPERAND_DCR : 1060 1.1 christos fields->f_r1 = value; 1061 1.1 christos break; 1062 1.1 christos case M32R_OPERAND_DISP16 : 1063 1.1 christos fields->f_disp16 = value; 1064 1.1 christos break; 1065 1.1 christos case M32R_OPERAND_DISP24 : 1066 1.1 christos fields->f_disp24 = value; 1067 1.1 christos break; 1068 1.1 christos case M32R_OPERAND_DISP8 : 1069 1.1 christos fields->f_disp8 = value; 1070 1.1 christos break; 1071 1.1 christos case M32R_OPERAND_DR : 1072 1.1 christos fields->f_r1 = value; 1073 1.1 christos break; 1074 1.1 christos case M32R_OPERAND_HASH : 1075 1.1 christos break; 1076 1.1 christos case M32R_OPERAND_HI16 : 1077 1.1 christos fields->f_hi16 = value; 1078 1.1 christos break; 1079 1.1 christos case M32R_OPERAND_IMM1 : 1080 1.1 christos fields->f_imm1 = value; 1081 1.1 christos break; 1082 1.1 christos case M32R_OPERAND_SCR : 1083 1.1 christos fields->f_r2 = value; 1084 1.1 christos break; 1085 1.1 christos case M32R_OPERAND_SIMM16 : 1086 1.1 christos fields->f_simm16 = value; 1087 1.1 christos break; 1088 1.1 christos case M32R_OPERAND_SIMM8 : 1089 1.1 christos fields->f_simm8 = value; 1090 1.1 christos break; 1091 1.1 christos case M32R_OPERAND_SLO16 : 1092 1.1 christos fields->f_simm16 = value; 1093 1.1 christos break; 1094 1.1 christos case M32R_OPERAND_SR : 1095 1.1 christos fields->f_r2 = value; 1096 1.1 christos break; 1097 1.1 christos case M32R_OPERAND_SRC1 : 1098 1.1 christos fields->f_r1 = value; 1099 1.1 christos break; 1100 1.1 christos case M32R_OPERAND_SRC2 : 1101 1.1 christos fields->f_r2 = value; 1102 1.1 christos break; 1103 1.1 christos case M32R_OPERAND_UIMM16 : 1104 1.1 christos fields->f_uimm16 = value; 1105 1.1 christos break; 1106 1.1 christos case M32R_OPERAND_UIMM24 : 1107 1.1 christos fields->f_uimm24 = value; 1108 1.1 christos break; 1109 1.1 christos case M32R_OPERAND_UIMM3 : 1110 1.1 christos fields->f_uimm3 = value; 1111 1.1 christos break; 1112 1.1 christos case M32R_OPERAND_UIMM4 : 1113 1.1 christos fields->f_uimm4 = value; 1114 1.1 christos break; 1115 1.1 christos case M32R_OPERAND_UIMM5 : 1116 1.1 christos fields->f_uimm5 = value; 1117 1.1 christos break; 1118 1.1 christos case M32R_OPERAND_UIMM8 : 1119 1.1 christos fields->f_uimm8 = value; 1120 1.1 christos break; 1121 1.1 christos case M32R_OPERAND_ULO16 : 1122 1.1 christos fields->f_uimm16 = value; 1123 1.1 christos break; 1124 1.1.1.5 christos 1125 1.1.1.5 christos default : 1126 1.1.1.5 christos /* xgettext:c-format */ 1127 1.1 christos opcodes_error_handler 1128 1.1 christos (_("internal error: unrecognized field %d while setting int operand"), 1129 1.1 christos opindex); 1130 1.1 christos abort (); 1131 1.1 christos } 1132 1.1 christos } 1133 1.1 christos 1134 1.1 christos void 1135 1.1 christos m32r_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 1136 1.1 christos int opindex, 1137 1.1 christos CGEN_FIELDS * fields, 1138 1.1 christos bfd_vma value) 1139 1.1 christos { 1140 1.1 christos switch (opindex) 1141 1.1 christos { 1142 1.1 christos case M32R_OPERAND_ACC : 1143 1.1 christos fields->f_acc = value; 1144 1.1 christos break; 1145 1.1 christos case M32R_OPERAND_ACCD : 1146 1.1 christos fields->f_accd = value; 1147 1.1 christos break; 1148 1.1 christos case M32R_OPERAND_ACCS : 1149 1.1 christos fields->f_accs = value; 1150 1.1 christos break; 1151 1.1 christos case M32R_OPERAND_DCR : 1152 1.1 christos fields->f_r1 = value; 1153 1.1 christos break; 1154 1.1 christos case M32R_OPERAND_DISP16 : 1155 1.1 christos fields->f_disp16 = value; 1156 1.1 christos break; 1157 1.1 christos case M32R_OPERAND_DISP24 : 1158 1.1 christos fields->f_disp24 = value; 1159 1.1 christos break; 1160 1.1 christos case M32R_OPERAND_DISP8 : 1161 1.1 christos fields->f_disp8 = value; 1162 1.1 christos break; 1163 1.1 christos case M32R_OPERAND_DR : 1164 1.1 christos fields->f_r1 = value; 1165 1.1 christos break; 1166 1.1 christos case M32R_OPERAND_HASH : 1167 1.1 christos break; 1168 1.1 christos case M32R_OPERAND_HI16 : 1169 1.1 christos fields->f_hi16 = value; 1170 1.1 christos break; 1171 1.1 christos case M32R_OPERAND_IMM1 : 1172 1.1 christos fields->f_imm1 = value; 1173 1.1 christos break; 1174 1.1 christos case M32R_OPERAND_SCR : 1175 1.1 christos fields->f_r2 = value; 1176 1.1 christos break; 1177 1.1 christos case M32R_OPERAND_SIMM16 : 1178 1.1 christos fields->f_simm16 = value; 1179 1.1 christos break; 1180 1.1 christos case M32R_OPERAND_SIMM8 : 1181 1.1 christos fields->f_simm8 = value; 1182 1.1 christos break; 1183 1.1 christos case M32R_OPERAND_SLO16 : 1184 1.1 christos fields->f_simm16 = value; 1185 1.1 christos break; 1186 1.1 christos case M32R_OPERAND_SR : 1187 1.1 christos fields->f_r2 = value; 1188 1.1 christos break; 1189 1.1 christos case M32R_OPERAND_SRC1 : 1190 1.1 christos fields->f_r1 = value; 1191 1.1 christos break; 1192 1.1 christos case M32R_OPERAND_SRC2 : 1193 1.1 christos fields->f_r2 = value; 1194 1.1 christos break; 1195 1.1 christos case M32R_OPERAND_UIMM16 : 1196 1.1 christos fields->f_uimm16 = value; 1197 1.1 christos break; 1198 1.1 christos case M32R_OPERAND_UIMM24 : 1199 1.1 christos fields->f_uimm24 = value; 1200 1.1 christos break; 1201 1.1 christos case M32R_OPERAND_UIMM3 : 1202 1.1 christos fields->f_uimm3 = value; 1203 1.1 christos break; 1204 1.1 christos case M32R_OPERAND_UIMM4 : 1205 1.1 christos fields->f_uimm4 = value; 1206 1.1 christos break; 1207 1.1 christos case M32R_OPERAND_UIMM5 : 1208 1.1 christos fields->f_uimm5 = value; 1209 1.1 christos break; 1210 1.1 christos case M32R_OPERAND_UIMM8 : 1211 1.1 christos fields->f_uimm8 = value; 1212 1.1 christos break; 1213 1.1 christos case M32R_OPERAND_ULO16 : 1214 1.1 christos fields->f_uimm16 = value; 1215 1.1 christos break; 1216 1.1.1.5 christos 1217 1.1.1.5 christos default : 1218 1.1.1.5 christos /* xgettext:c-format */ 1219 1.1 christos opcodes_error_handler 1220 1.1 christos (_("internal error: unrecognized field %d while setting vma operand"), 1221 1.1 christos opindex); 1222 1.1 christos abort (); 1223 1.1 christos } 1224 1.1 christos } 1225 1.1 christos 1226 1.1 christos /* Function to call before using the instruction builder tables. */ 1227 1.1 christos 1228 1.1 christos void 1229 1.1 christos m32r_cgen_init_ibld_table (CGEN_CPU_DESC cd) 1230 1.1 christos { 1231 1.1 christos cd->insert_handlers = & m32r_cgen_insert_handlers[0]; 1232 1.1 christos cd->extract_handlers = & m32r_cgen_extract_handlers[0]; 1233 1.1 christos 1234 1.1 christos cd->insert_operand = m32r_cgen_insert_operand; 1235 1.1 christos cd->extract_operand = m32r_cgen_extract_operand; 1236 1.1 christos 1237 1.1 christos cd->get_int_operand = m32r_cgen_get_int_operand; 1238 1.1 christos cd->set_int_operand = m32r_cgen_set_int_operand; 1239 cd->get_vma_operand = m32r_cgen_get_vma_operand; 1240 cd->set_vma_operand = m32r_cgen_set_vma_operand; 1241 } 1242