1 1.1 christos /* tc-bfin.c -- Assembler for the ADI Blackfin. 2 1.10 christos Copyright (C) 2005-2025 Free Software Foundation, Inc. 3 1.1 christos 4 1.1 christos This file is part of GAS, the GNU Assembler. 5 1.1 christos 6 1.1 christos GAS is free software; you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3, or (at your option) 9 1.1 christos any later version. 10 1.1 christos 11 1.1 christos GAS is distributed in the hope that it will be useful, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 christos GNU General Public License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with GAS; see the file COPYING. If not, write to the Free 18 1.1 christos Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 19 1.1 christos 02110-1301, USA. */ 20 1.1 christos 21 1.1 christos #include "as.h" 22 1.1 christos #include "bfin-defs.h" 23 1.1 christos #include "obstack.h" 24 1.1 christos #include "safe-ctype.h" 25 1.1 christos #ifdef OBJ_ELF 26 1.1 christos #include "dwarf2dbg.h" 27 1.1 christos #endif 28 1.1 christos #include "elf/common.h" 29 1.1 christos #include "elf/bfin.h" 30 1.1 christos 31 1.1 christos extern int yyparse (void); 32 1.1 christos struct yy_buffer_state; 33 1.1 christos typedef struct yy_buffer_state *YY_BUFFER_STATE; 34 1.1 christos extern YY_BUFFER_STATE yy_scan_string (const char *yy_str); 35 1.1 christos extern void yy_delete_buffer (YY_BUFFER_STATE b); 36 1.1 christos static parse_state parse (char *line); 37 1.1 christos 38 1.1 christos /* Global variables. */ 39 1.1 christos struct bfin_insn *insn; 40 1.1 christos int last_insn_size; 41 1.1 christos 42 1.1 christos extern struct obstack mempool; 43 1.1 christos FILE *errorf; 44 1.1 christos 45 1.1 christos /* Flags to set in the elf header */ 46 1.1 christos #define DEFAULT_FLAGS 0 47 1.1 christos 48 1.1 christos #ifdef OBJ_FDPIC_ELF 49 1.1 christos # define DEFAULT_FDPIC EF_BFIN_FDPIC 50 1.1 christos #else 51 1.1 christos # define DEFAULT_FDPIC 0 52 1.1 christos #endif 53 1.1 christos 54 1.1 christos static flagword bfin_flags = DEFAULT_FLAGS | DEFAULT_FDPIC; 55 1.10 christos static const char *bfin_pic_flag = DEFAULT_FDPIC ? "-mfdpic" : NULL; 56 1.1 christos 57 1.1 christos /* Blackfin specific function to handle FD-PIC pointer initializations. */ 58 1.1 christos 59 1.1 christos static void 60 1.1 christos bfin_pic_ptr (int nbytes) 61 1.1 christos { 62 1.1 christos expressionS exp; 63 1.1 christos char *p; 64 1.1 christos 65 1.1 christos if (nbytes != 4) 66 1.1 christos abort (); 67 1.1 christos 68 1.1 christos #ifdef md_flush_pending_output 69 1.1 christos md_flush_pending_output (); 70 1.1 christos #endif 71 1.1 christos 72 1.1 christos if (is_it_end_of_statement ()) 73 1.1 christos { 74 1.1 christos demand_empty_rest_of_line (); 75 1.1 christos return; 76 1.1 christos } 77 1.1 christos 78 1.1 christos #ifdef md_cons_align 79 1.1 christos md_cons_align (nbytes); 80 1.1 christos #endif 81 1.1 christos 82 1.1 christos do 83 1.1 christos { 84 1.1 christos bfd_reloc_code_real_type reloc_type = BFD_RELOC_BFIN_FUNCDESC; 85 1.1 christos 86 1.1 christos if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0) 87 1.1 christos { 88 1.1 christos input_line_pointer += 9; 89 1.1 christos expression (&exp); 90 1.1 christos if (*input_line_pointer == ')') 91 1.1 christos input_line_pointer++; 92 1.1 christos else 93 1.1 christos as_bad (_("missing ')'")); 94 1.1 christos } 95 1.1 christos else 96 1.1 christos error ("missing funcdesc in picptr"); 97 1.1 christos 98 1.1 christos p = frag_more (4); 99 1.1 christos memset (p, 0, 4); 100 1.1 christos fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &exp, 0, 101 1.1 christos reloc_type); 102 1.1 christos } 103 1.1 christos while (*input_line_pointer++ == ','); 104 1.1 christos 105 1.1 christos input_line_pointer--; /* Put terminator back into stream. */ 106 1.1 christos demand_empty_rest_of_line (); 107 1.1 christos } 108 1.1 christos 109 1.1 christos const pseudo_typeS md_pseudo_table[] = { 110 1.1 christos {"align", s_align_bytes, 0}, 111 1.1 christos {"byte2", cons, 2}, 112 1.1 christos {"byte4", cons, 4}, 113 1.1 christos {"picptr", bfin_pic_ptr, 4}, 114 1.1 christos {"code", obj_elf_section, 0}, 115 1.1 christos {"db", cons, 1}, 116 1.1 christos {"dd", cons, 4}, 117 1.1 christos {"dw", cons, 2}, 118 1.1 christos {"p", s_ignore, 0}, 119 1.1 christos {"pdata", s_ignore, 0}, 120 1.1 christos {"var", s_ignore, 0}, 121 1.1 christos {0, 0, 0} 122 1.1 christos }; 123 1.1 christos 124 1.1 christos /* Characters that are used to denote comments and line separators. */ 125 1.1 christos const char comment_chars[] = "#"; 126 1.1 christos const char line_comment_chars[] = "#"; 127 1.1 christos const char line_separator_chars[] = ";"; 128 1.1 christos 129 1.1 christos /* Characters that can be used to separate the mantissa from the 130 1.1 christos exponent in floating point numbers. */ 131 1.1 christos const char EXP_CHARS[] = "eE"; 132 1.1 christos 133 1.1 christos /* Characters that mean this number is a floating point constant. 134 1.1 christos As in 0f12.456 or 0d1.2345e12. */ 135 1.1 christos const char FLT_CHARS[] = "fFdDxX"; 136 1.1 christos 137 1.1 christos typedef enum bfin_cpu_type 138 1.1 christos { 139 1.1 christos BFIN_CPU_UNKNOWN, 140 1.1 christos BFIN_CPU_BF504, 141 1.1 christos BFIN_CPU_BF506, 142 1.1 christos BFIN_CPU_BF512, 143 1.1 christos BFIN_CPU_BF514, 144 1.1 christos BFIN_CPU_BF516, 145 1.1 christos BFIN_CPU_BF518, 146 1.1 christos BFIN_CPU_BF522, 147 1.1 christos BFIN_CPU_BF523, 148 1.1 christos BFIN_CPU_BF524, 149 1.1 christos BFIN_CPU_BF525, 150 1.1 christos BFIN_CPU_BF526, 151 1.1 christos BFIN_CPU_BF527, 152 1.1 christos BFIN_CPU_BF531, 153 1.1 christos BFIN_CPU_BF532, 154 1.1 christos BFIN_CPU_BF533, 155 1.1 christos BFIN_CPU_BF534, 156 1.1 christos BFIN_CPU_BF536, 157 1.1 christos BFIN_CPU_BF537, 158 1.1 christos BFIN_CPU_BF538, 159 1.1 christos BFIN_CPU_BF539, 160 1.1 christos BFIN_CPU_BF542, 161 1.1 christos BFIN_CPU_BF542M, 162 1.1 christos BFIN_CPU_BF544, 163 1.1 christos BFIN_CPU_BF544M, 164 1.1 christos BFIN_CPU_BF547, 165 1.1 christos BFIN_CPU_BF547M, 166 1.1 christos BFIN_CPU_BF548, 167 1.1 christos BFIN_CPU_BF548M, 168 1.1 christos BFIN_CPU_BF549, 169 1.1 christos BFIN_CPU_BF549M, 170 1.1 christos BFIN_CPU_BF561, 171 1.1 christos BFIN_CPU_BF592, 172 1.1 christos } bfin_cpu_t; 173 1.1 christos 174 1.1 christos bfin_cpu_t bfin_cpu_type = BFIN_CPU_UNKNOWN; 175 1.1 christos /* -msi-revision support. There are three special values: 176 1.1 christos -1 -msi-revision=none. 177 1.1 christos 0xffff -msi-revision=any. */ 178 1.1 christos int bfin_si_revision; 179 1.1 christos 180 1.1 christos unsigned int bfin_anomaly_checks = 0; 181 1.1 christos 182 1.1 christos struct bfin_cpu 183 1.1 christos { 184 1.1 christos const char *name; 185 1.1 christos bfin_cpu_t type; 186 1.1 christos int si_revision; 187 1.1 christos unsigned int anomaly_checks; 188 1.1 christos }; 189 1.1 christos 190 1.1 christos struct bfin_cpu bfin_cpus[] = 191 1.1 christos { 192 1.1 christos {"bf504", BFIN_CPU_BF504, 0x0000, AC_05000074}, 193 1.1 christos 194 1.1 christos {"bf506", BFIN_CPU_BF506, 0x0000, AC_05000074}, 195 1.1 christos 196 1.1 christos {"bf512", BFIN_CPU_BF512, 0x0002, AC_05000074}, 197 1.1 christos {"bf512", BFIN_CPU_BF512, 0x0001, AC_05000074}, 198 1.1 christos {"bf512", BFIN_CPU_BF512, 0x0000, AC_05000074}, 199 1.1 christos 200 1.1 christos {"bf514", BFIN_CPU_BF514, 0x0002, AC_05000074}, 201 1.1 christos {"bf514", BFIN_CPU_BF514, 0x0001, AC_05000074}, 202 1.1 christos {"bf514", BFIN_CPU_BF514, 0x0000, AC_05000074}, 203 1.1 christos 204 1.1 christos {"bf516", BFIN_CPU_BF516, 0x0002, AC_05000074}, 205 1.1 christos {"bf516", BFIN_CPU_BF516, 0x0001, AC_05000074}, 206 1.1 christos {"bf516", BFIN_CPU_BF516, 0x0000, AC_05000074}, 207 1.1 christos 208 1.1 christos {"bf518", BFIN_CPU_BF518, 0x0002, AC_05000074}, 209 1.1 christos {"bf518", BFIN_CPU_BF518, 0x0001, AC_05000074}, 210 1.1 christos {"bf518", BFIN_CPU_BF518, 0x0000, AC_05000074}, 211 1.1 christos 212 1.1 christos {"bf522", BFIN_CPU_BF522, 0x0002, AC_05000074}, 213 1.1 christos {"bf522", BFIN_CPU_BF522, 0x0001, AC_05000074}, 214 1.1 christos {"bf522", BFIN_CPU_BF522, 0x0000, AC_05000074}, 215 1.1 christos 216 1.1 christos {"bf523", BFIN_CPU_BF523, 0x0002, AC_05000074}, 217 1.1 christos {"bf523", BFIN_CPU_BF523, 0x0001, AC_05000074}, 218 1.1 christos {"bf523", BFIN_CPU_BF523, 0x0000, AC_05000074}, 219 1.1 christos 220 1.1 christos {"bf524", BFIN_CPU_BF524, 0x0002, AC_05000074}, 221 1.1 christos {"bf524", BFIN_CPU_BF524, 0x0001, AC_05000074}, 222 1.1 christos {"bf524", BFIN_CPU_BF524, 0x0000, AC_05000074}, 223 1.1 christos 224 1.1 christos {"bf525", BFIN_CPU_BF525, 0x0002, AC_05000074}, 225 1.1 christos {"bf525", BFIN_CPU_BF525, 0x0001, AC_05000074}, 226 1.1 christos {"bf525", BFIN_CPU_BF525, 0x0000, AC_05000074}, 227 1.1 christos 228 1.1 christos {"bf526", BFIN_CPU_BF526, 0x0002, AC_05000074}, 229 1.1 christos {"bf526", BFIN_CPU_BF526, 0x0001, AC_05000074}, 230 1.1 christos {"bf526", BFIN_CPU_BF526, 0x0000, AC_05000074}, 231 1.1 christos 232 1.1 christos {"bf527", BFIN_CPU_BF527, 0x0002, AC_05000074}, 233 1.1 christos {"bf527", BFIN_CPU_BF527, 0x0001, AC_05000074}, 234 1.1 christos {"bf527", BFIN_CPU_BF527, 0x0000, AC_05000074}, 235 1.1 christos 236 1.1 christos {"bf531", BFIN_CPU_BF531, 0x0006, AC_05000074}, 237 1.1 christos {"bf531", BFIN_CPU_BF531, 0x0005, AC_05000074}, 238 1.1 christos {"bf531", BFIN_CPU_BF531, 0x0004, AC_05000074}, 239 1.1 christos {"bf531", BFIN_CPU_BF531, 0x0003, AC_05000074}, 240 1.1 christos 241 1.1 christos {"bf532", BFIN_CPU_BF532, 0x0006, AC_05000074}, 242 1.1 christos {"bf532", BFIN_CPU_BF532, 0x0005, AC_05000074}, 243 1.1 christos {"bf532", BFIN_CPU_BF532, 0x0004, AC_05000074}, 244 1.1 christos {"bf532", BFIN_CPU_BF532, 0x0003, AC_05000074}, 245 1.1 christos 246 1.1 christos {"bf533", BFIN_CPU_BF533, 0x0006, AC_05000074}, 247 1.1 christos {"bf533", BFIN_CPU_BF533, 0x0005, AC_05000074}, 248 1.1 christos {"bf533", BFIN_CPU_BF533, 0x0004, AC_05000074}, 249 1.1 christos {"bf533", BFIN_CPU_BF533, 0x0003, AC_05000074}, 250 1.1 christos 251 1.1 christos {"bf534", BFIN_CPU_BF534, 0x0003, AC_05000074}, 252 1.1 christos {"bf534", BFIN_CPU_BF534, 0x0002, AC_05000074}, 253 1.1 christos {"bf534", BFIN_CPU_BF534, 0x0001, AC_05000074}, 254 1.1 christos 255 1.1 christos {"bf536", BFIN_CPU_BF536, 0x0003, AC_05000074}, 256 1.1 christos {"bf536", BFIN_CPU_BF536, 0x0002, AC_05000074}, 257 1.1 christos {"bf536", BFIN_CPU_BF536, 0x0001, AC_05000074}, 258 1.1 christos 259 1.1 christos {"bf537", BFIN_CPU_BF537, 0x0003, AC_05000074}, 260 1.1 christos {"bf537", BFIN_CPU_BF537, 0x0002, AC_05000074}, 261 1.1 christos {"bf537", BFIN_CPU_BF537, 0x0001, AC_05000074}, 262 1.1 christos 263 1.1 christos {"bf538", BFIN_CPU_BF538, 0x0005, AC_05000074}, 264 1.1 christos {"bf538", BFIN_CPU_BF538, 0x0004, AC_05000074}, 265 1.1 christos {"bf538", BFIN_CPU_BF538, 0x0003, AC_05000074}, 266 1.1 christos {"bf538", BFIN_CPU_BF538, 0x0002, AC_05000074}, 267 1.1 christos 268 1.1 christos {"bf539", BFIN_CPU_BF539, 0x0005, AC_05000074}, 269 1.1 christos {"bf539", BFIN_CPU_BF539, 0x0004, AC_05000074}, 270 1.1 christos {"bf539", BFIN_CPU_BF539, 0x0003, AC_05000074}, 271 1.1 christos {"bf539", BFIN_CPU_BF539, 0x0002, AC_05000074}, 272 1.1 christos 273 1.1 christos {"bf542m", BFIN_CPU_BF542M, 0x0003, AC_05000074}, 274 1.1 christos 275 1.1 christos {"bf542", BFIN_CPU_BF542, 0x0004, AC_05000074}, 276 1.1 christos {"bf542", BFIN_CPU_BF542, 0x0002, AC_05000074}, 277 1.1 christos {"bf542", BFIN_CPU_BF542, 0x0001, AC_05000074}, 278 1.1 christos {"bf542", BFIN_CPU_BF542, 0x0000, AC_05000074}, 279 1.1 christos 280 1.1 christos {"bf544m", BFIN_CPU_BF544M, 0x0003, AC_05000074}, 281 1.1 christos 282 1.1 christos {"bf544", BFIN_CPU_BF544, 0x0004, AC_05000074}, 283 1.1 christos {"bf544", BFIN_CPU_BF544, 0x0002, AC_05000074}, 284 1.1 christos {"bf544", BFIN_CPU_BF544, 0x0001, AC_05000074}, 285 1.1 christos {"bf544", BFIN_CPU_BF544, 0x0000, AC_05000074}, 286 1.1 christos 287 1.1 christos {"bf547m", BFIN_CPU_BF547M, 0x0003, AC_05000074}, 288 1.1 christos 289 1.1 christos {"bf547", BFIN_CPU_BF547, 0x0004, AC_05000074}, 290 1.1 christos {"bf547", BFIN_CPU_BF547, 0x0002, AC_05000074}, 291 1.1 christos {"bf547", BFIN_CPU_BF547, 0x0001, AC_05000074}, 292 1.1 christos {"bf547", BFIN_CPU_BF547, 0x0000, AC_05000074}, 293 1.1 christos 294 1.1 christos {"bf548m", BFIN_CPU_BF548M, 0x0003, AC_05000074}, 295 1.1 christos 296 1.1 christos {"bf548", BFIN_CPU_BF548, 0x0004, AC_05000074}, 297 1.1 christos {"bf548", BFIN_CPU_BF548, 0x0002, AC_05000074}, 298 1.1 christos {"bf548", BFIN_CPU_BF548, 0x0001, AC_05000074}, 299 1.1 christos {"bf548", BFIN_CPU_BF548, 0x0000, AC_05000074}, 300 1.1 christos 301 1.1 christos {"bf549m", BFIN_CPU_BF549M, 0x0003, AC_05000074}, 302 1.1 christos 303 1.1 christos {"bf549", BFIN_CPU_BF549, 0x0004, AC_05000074}, 304 1.1 christos {"bf549", BFIN_CPU_BF549, 0x0002, AC_05000074}, 305 1.1 christos {"bf549", BFIN_CPU_BF549, 0x0001, AC_05000074}, 306 1.1 christos {"bf549", BFIN_CPU_BF549, 0x0000, AC_05000074}, 307 1.1 christos 308 1.1 christos {"bf561", BFIN_CPU_BF561, 0x0005, AC_05000074}, 309 1.1 christos {"bf561", BFIN_CPU_BF561, 0x0003, AC_05000074}, 310 1.1 christos {"bf561", BFIN_CPU_BF561, 0x0002, AC_05000074}, 311 1.1 christos 312 1.1 christos {"bf592", BFIN_CPU_BF592, 0x0001, AC_05000074}, 313 1.1 christos {"bf592", BFIN_CPU_BF592, 0x0000, AC_05000074}, 314 1.1 christos }; 315 1.1 christos 316 1.1 christos /* Define bfin-specific command-line options (there are none). */ 317 1.10 christos const char md_shortopts[] = ""; 318 1.1 christos 319 1.1 christos #define OPTION_FDPIC (OPTION_MD_BASE) 320 1.1 christos #define OPTION_NOPIC (OPTION_MD_BASE + 1) 321 1.1 christos #define OPTION_MCPU (OPTION_MD_BASE + 2) 322 1.1 christos 323 1.10 christos const struct option md_longopts[] = 324 1.1 christos { 325 1.1 christos { "mcpu", required_argument, NULL, OPTION_MCPU }, 326 1.1 christos { "mfdpic", no_argument, NULL, OPTION_FDPIC }, 327 1.1 christos { "mnopic", no_argument, NULL, OPTION_NOPIC }, 328 1.1 christos { "mno-fdpic", no_argument, NULL, OPTION_NOPIC }, 329 1.1 christos { NULL, no_argument, NULL, 0 }, 330 1.1 christos }; 331 1.1 christos 332 1.10 christos const size_t md_longopts_size = sizeof (md_longopts); 333 1.1 christos 334 1.1 christos 335 1.1 christos int 336 1.5 christos md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED) 337 1.1 christos { 338 1.1 christos switch (c) 339 1.1 christos { 340 1.1 christos default: 341 1.1 christos return 0; 342 1.1 christos 343 1.1 christos case OPTION_MCPU: 344 1.1 christos { 345 1.5 christos const char *q; 346 1.5 christos unsigned int i; 347 1.1 christos 348 1.5 christos for (i = 0; i < ARRAY_SIZE (bfin_cpus); i++) 349 1.1 christos { 350 1.5 christos const char *p = bfin_cpus[i].name; 351 1.1 christos if (strncmp (arg, p, strlen (p)) == 0) 352 1.1 christos break; 353 1.1 christos } 354 1.1 christos 355 1.5 christos if (i == ARRAY_SIZE (bfin_cpus)) 356 1.1 christos as_fatal ("-mcpu=%s is not valid", arg); 357 1.1 christos 358 1.1 christos bfin_cpu_type = bfin_cpus[i].type; 359 1.1 christos 360 1.5 christos q = arg + strlen (bfin_cpus[i].name); 361 1.1 christos 362 1.1 christos if (*q == '\0') 363 1.1 christos { 364 1.1 christos bfin_si_revision = bfin_cpus[i].si_revision; 365 1.1 christos bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks; 366 1.1 christos } 367 1.1 christos else if (strcmp (q, "-none") == 0) 368 1.1 christos bfin_si_revision = -1; 369 1.1 christos else if (strcmp (q, "-any") == 0) 370 1.1 christos { 371 1.1 christos bfin_si_revision = 0xffff; 372 1.5 christos while (i < ARRAY_SIZE (bfin_cpus) 373 1.5 christos && bfin_cpus[i].type == bfin_cpu_type) 374 1.1 christos { 375 1.1 christos bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks; 376 1.1 christos i++; 377 1.1 christos } 378 1.1 christos } 379 1.1 christos else 380 1.1 christos { 381 1.1 christos unsigned int si_major, si_minor; 382 1.1 christos int rev_len, n; 383 1.1 christos 384 1.1 christos rev_len = strlen (q); 385 1.1 christos 386 1.1 christos if (sscanf (q, "-%u.%u%n", &si_major, &si_minor, &n) != 2 387 1.1 christos || n != rev_len 388 1.1 christos || si_major > 0xff || si_minor > 0xff) 389 1.1 christos { 390 1.1 christos invalid_silicon_revision: 391 1.1 christos as_fatal ("-mcpu=%s has invalid silicon revision", arg); 392 1.1 christos } 393 1.1 christos 394 1.1 christos bfin_si_revision = (si_major << 8) | si_minor; 395 1.1 christos 396 1.5 christos while (i < ARRAY_SIZE (bfin_cpus) 397 1.5 christos && bfin_cpus[i].type == bfin_cpu_type 398 1.1 christos && bfin_cpus[i].si_revision != bfin_si_revision) 399 1.1 christos i++; 400 1.1 christos 401 1.5 christos if (i == ARRAY_SIZE (bfin_cpus) 402 1.5 christos || bfin_cpus[i].type != bfin_cpu_type) 403 1.1 christos goto invalid_silicon_revision; 404 1.1 christos 405 1.1 christos bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks; 406 1.1 christos } 407 1.1 christos 408 1.1 christos break; 409 1.1 christos } 410 1.1 christos 411 1.1 christos case OPTION_FDPIC: 412 1.1 christos bfin_flags |= EF_BFIN_FDPIC; 413 1.1 christos bfin_pic_flag = "-mfdpic"; 414 1.1 christos break; 415 1.1 christos 416 1.1 christos case OPTION_NOPIC: 417 1.1 christos bfin_flags &= ~(EF_BFIN_FDPIC); 418 1.1 christos bfin_pic_flag = 0; 419 1.1 christos break; 420 1.1 christos } 421 1.1 christos 422 1.1 christos return 1; 423 1.1 christos } 424 1.1 christos 425 1.1 christos void 426 1.1 christos md_show_usage (FILE * stream) 427 1.1 christos { 428 1.1 christos fprintf (stream, _(" Blackfin specific assembler options:\n")); 429 1.1 christos fprintf (stream, _(" -mcpu=<cpu[-sirevision]> specify the name of the target CPU\n")); 430 1.1 christos fprintf (stream, _(" -mfdpic assemble for the FDPIC ABI\n")); 431 1.1 christos fprintf (stream, _(" -mno-fdpic/-mnopic disable -mfdpic\n")); 432 1.1 christos } 433 1.1 christos 434 1.1 christos /* Perform machine-specific initializations. */ 435 1.1 christos void 436 1.5 christos md_begin (void) 437 1.1 christos { 438 1.1 christos /* Set the ELF flags if desired. */ 439 1.1 christos if (bfin_flags) 440 1.1 christos bfd_set_private_flags (stdoutput, bfin_flags); 441 1.1 christos 442 1.1 christos /* Set the default machine type. */ 443 1.1 christos if (!bfd_set_arch_mach (stdoutput, bfd_arch_bfin, 0)) 444 1.1 christos as_warn (_("Could not set architecture and machine.")); 445 1.1 christos 446 1.1 christos /* Ensure that lines can begin with '(', for multiple 447 1.1 christos register stack pops. */ 448 1.1 christos lex_type ['('] = LEX_BEGIN_NAME; 449 1.1 christos 450 1.1 christos #ifdef OBJ_ELF 451 1.1 christos record_alignment (text_section, 2); 452 1.1 christos record_alignment (data_section, 2); 453 1.1 christos record_alignment (bss_section, 2); 454 1.1 christos #endif 455 1.1 christos 456 1.1 christos errorf = stderr; 457 1.1 christos obstack_init (&mempool); 458 1.1 christos 459 1.1 christos #ifdef DEBUG 460 1.1 christos extern int debug_codeselection; 461 1.1 christos debug_codeselection = 1; 462 1.1 christos #endif 463 1.1 christos 464 1.1 christos last_insn_size = 0; 465 1.1 christos } 466 1.1 christos 467 1.1 christos /* Perform the main parsing, and assembly of the input here. Also, 468 1.1 christos call the required routines for alignment and fixups here. 469 1.1 christos This is called for every line that contains real assembly code. */ 470 1.1 christos 471 1.1 christos void 472 1.1 christos md_assemble (char *line) 473 1.1 christos { 474 1.1 christos char *toP = 0; 475 1.1 christos int size, insn_size; 476 1.1 christos struct bfin_insn *tmp_insn; 477 1.1 christos size_t len; 478 1.1 christos static size_t buffer_len = 0; 479 1.5 christos static char *current_inputline; 480 1.1 christos parse_state state; 481 1.1 christos 482 1.1 christos len = strlen (line); 483 1.1 christos if (len + 2 > buffer_len) 484 1.1 christos { 485 1.1 christos buffer_len = len + 40; 486 1.5 christos current_inputline = XRESIZEVEC (char, current_inputline, buffer_len); 487 1.1 christos } 488 1.1 christos memcpy (current_inputline, line, len); 489 1.1 christos current_inputline[len] = ';'; 490 1.1 christos current_inputline[len + 1] = '\0'; 491 1.1 christos 492 1.1 christos state = parse (current_inputline); 493 1.1 christos if (state == NO_INSN_GENERATED) 494 1.1 christos return; 495 1.1 christos 496 1.1 christos for (insn_size = 0, tmp_insn = insn; tmp_insn; tmp_insn = tmp_insn->next) 497 1.1 christos if (!tmp_insn->reloc || !tmp_insn->exp->symbol) 498 1.1 christos insn_size += 2; 499 1.1 christos 500 1.1 christos if (insn_size) 501 1.1 christos toP = frag_more (insn_size); 502 1.1 christos 503 1.1 christos last_insn_size = insn_size; 504 1.1 christos 505 1.1 christos #ifdef DEBUG 506 1.1 christos printf ("INS:"); 507 1.1 christos #endif 508 1.1 christos while (insn) 509 1.1 christos { 510 1.1 christos if (insn->reloc && insn->exp->symbol) 511 1.1 christos { 512 1.1 christos char *prev_toP = toP - 2; 513 1.1 christos switch (insn->reloc) 514 1.1 christos { 515 1.1 christos case BFD_RELOC_BFIN_24_PCREL_JUMP_L: 516 1.1 christos case BFD_RELOC_24_PCREL: 517 1.1 christos case BFD_RELOC_BFIN_16_LOW: 518 1.1 christos case BFD_RELOC_BFIN_16_HIGH: 519 1.1 christos size = 4; 520 1.1 christos break; 521 1.1 christos default: 522 1.1 christos size = 2; 523 1.1 christos } 524 1.1 christos 525 1.1 christos /* Following if condition checks for the arithmetic relocations. 526 1.1 christos If the case then it doesn't required to generate the code. 527 1.1 christos It has been assumed that, their ID will be contiguous. */ 528 1.1 christos if ((BFD_ARELOC_BFIN_PUSH <= insn->reloc 529 1.1 christos && BFD_ARELOC_BFIN_COMP >= insn->reloc) 530 1.1 christos || insn->reloc == BFD_RELOC_BFIN_16_IMM) 531 1.1 christos { 532 1.1 christos size = 2; 533 1.1 christos } 534 1.1 christos if (insn->reloc == BFD_ARELOC_BFIN_CONST 535 1.1 christos || insn->reloc == BFD_ARELOC_BFIN_PUSH) 536 1.1 christos size = 4; 537 1.1 christos 538 1.1 christos fix_new (frag_now, 539 1.1 christos (prev_toP - frag_now->fr_literal), 540 1.1 christos size, insn->exp->symbol, insn->exp->value, 541 1.1 christos insn->pcrel, insn->reloc); 542 1.1 christos } 543 1.1 christos else 544 1.1 christos { 545 1.1 christos md_number_to_chars (toP, insn->value, 2); 546 1.1 christos toP += 2; 547 1.1 christos } 548 1.1 christos 549 1.1 christos #ifdef DEBUG 550 1.1 christos printf (" reloc :"); 551 1.1 christos printf (" %02x%02x", ((unsigned char *) &insn->value)[0], 552 1.1 christos ((unsigned char *) &insn->value)[1]); 553 1.1 christos printf ("\n"); 554 1.1 christos #endif 555 1.1 christos insn = insn->next; 556 1.1 christos } 557 1.1 christos #ifdef OBJ_ELF 558 1.1 christos dwarf2_emit_insn (insn_size); 559 1.1 christos #endif 560 1.1 christos 561 1.1 christos while (*line++ != '\0') 562 1.1 christos if (*line == '\n') 563 1.1 christos bump_line_counters (); 564 1.1 christos } 565 1.1 christos 566 1.1 christos /* Parse one line of instructions, and generate opcode for it. 567 1.1 christos To parse the line, YACC and LEX are used, because the instruction set 568 1.1 christos syntax doesn't confirm to the AT&T assembly syntax. 569 1.1 christos To call a YACC & LEX generated parser, we must provide the input via 570 1.1 christos a FILE stream, otherwise stdin is used by default. Below the input 571 1.1 christos to the function will be put into a temporary file, then the generated 572 1.1 christos parser uses the temporary file for parsing. */ 573 1.1 christos 574 1.1 christos static parse_state 575 1.1 christos parse (char *line) 576 1.1 christos { 577 1.1 christos parse_state state; 578 1.1 christos YY_BUFFER_STATE buffstate; 579 1.1 christos 580 1.1 christos buffstate = yy_scan_string (line); 581 1.1 christos 582 1.1 christos /* our lex requires setting the start state to keyword 583 1.1 christos every line as the first word may be a keyword. 584 1.1 christos Fixes a bug where we could not have keywords as labels. */ 585 1.1 christos set_start_state (); 586 1.1 christos 587 1.1 christos /* Call yyparse here. */ 588 1.1 christos state = yyparse (); 589 1.1 christos if (state == SEMANTIC_ERROR) 590 1.1 christos { 591 1.1 christos as_bad (_("Parse failed.")); 592 1.1 christos insn = 0; 593 1.1 christos } 594 1.1 christos 595 1.1 christos yy_delete_buffer (buffstate); 596 1.1 christos return state; 597 1.1 christos } 598 1.1 christos 599 1.1 christos /* We need to handle various expressions properly. 600 1.1 christos Such as, [SP--] = 34, concerned by md_assemble(). */ 601 1.1 christos 602 1.1 christos void 603 1.1 christos md_operand (expressionS * expressionP) 604 1.1 christos { 605 1.1 christos if (*input_line_pointer == '[') 606 1.1 christos { 607 1.1 christos as_tsktsk ("We found a '['!"); 608 1.1 christos input_line_pointer++; 609 1.1 christos expression (expressionP); 610 1.1 christos } 611 1.1 christos } 612 1.1 christos 613 1.1 christos /* Handle undefined symbols. */ 614 1.1 christos symbolS * 615 1.1 christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 616 1.1 christos { 617 1.10 christos return NULL; 618 1.1 christos } 619 1.1 christos 620 1.1 christos int 621 1.1 christos md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, 622 1.1 christos segT segment ATTRIBUTE_UNUSED) 623 1.1 christos { 624 1.1 christos return 0; 625 1.1 christos } 626 1.1 christos 627 1.1 christos /* Convert from target byte order to host byte order. */ 628 1.1 christos 629 1.1 christos static int 630 1.1 christos md_chars_to_number (char *val, int n) 631 1.1 christos { 632 1.1 christos int retval; 633 1.1 christos 634 1.1 christos for (retval = 0; n--;) 635 1.1 christos { 636 1.1 christos retval <<= 8; 637 1.1 christos retval |= val[n]; 638 1.1 christos } 639 1.1 christos return retval; 640 1.1 christos } 641 1.1 christos 642 1.1 christos void 643 1.1 christos md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED) 644 1.1 christos { 645 1.1 christos char *where = fixP->fx_frag->fr_literal + fixP->fx_where; 646 1.1 christos 647 1.1 christos long value = *valueP; 648 1.1 christos long newval; 649 1.1 christos 650 1.1 christos switch (fixP->fx_r_type) 651 1.1 christos { 652 1.1 christos case BFD_RELOC_BFIN_GOT: 653 1.1 christos case BFD_RELOC_BFIN_GOT17M4: 654 1.1 christos case BFD_RELOC_BFIN_FUNCDESC_GOT17M4: 655 1.1 christos fixP->fx_no_overflow = 1; 656 1.1 christos newval = md_chars_to_number (where, 2); 657 1.1 christos newval |= 0x0 & 0x7f; 658 1.1 christos md_number_to_chars (where, newval, 2); 659 1.1 christos break; 660 1.1 christos 661 1.1 christos case BFD_RELOC_BFIN_10_PCREL: 662 1.1 christos if (!value) 663 1.1 christos break; 664 1.1 christos if (value < -1024 || value > 1022) 665 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, 666 1.1 christos _("pcrel too far BFD_RELOC_BFIN_10")); 667 1.1 christos 668 1.1 christos /* 11 bit offset even numbered, so we remove right bit. */ 669 1.1 christos value = value >> 1; 670 1.1 christos newval = md_chars_to_number (where, 2); 671 1.1 christos newval |= value & 0x03ff; 672 1.1 christos md_number_to_chars (where, newval, 2); 673 1.1 christos break; 674 1.1 christos 675 1.1 christos case BFD_RELOC_BFIN_12_PCREL_JUMP: 676 1.1 christos case BFD_RELOC_BFIN_12_PCREL_JUMP_S: 677 1.1 christos case BFD_RELOC_12_PCREL: 678 1.1 christos if (!value) 679 1.1 christos break; 680 1.1 christos 681 1.1 christos if (value < -4096 || value > 4094) 682 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_12")); 683 1.1 christos /* 13 bit offset even numbered, so we remove right bit. */ 684 1.1 christos value = value >> 1; 685 1.1 christos newval = md_chars_to_number (where, 2); 686 1.1 christos newval |= value & 0xfff; 687 1.1 christos md_number_to_chars (where, newval, 2); 688 1.1 christos break; 689 1.1 christos 690 1.1 christos case BFD_RELOC_BFIN_16_LOW: 691 1.1 christos case BFD_RELOC_BFIN_16_HIGH: 692 1.8 christos fixP->fx_done = false; 693 1.1 christos break; 694 1.1 christos 695 1.1 christos case BFD_RELOC_BFIN_24_PCREL_JUMP_L: 696 1.1 christos case BFD_RELOC_BFIN_24_PCREL_CALL_X: 697 1.1 christos case BFD_RELOC_24_PCREL: 698 1.1 christos if (!value) 699 1.1 christos break; 700 1.1 christos 701 1.1 christos if (value < -16777216 || value > 16777214) 702 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_24")); 703 1.1 christos 704 1.1 christos /* 25 bit offset even numbered, so we remove right bit. */ 705 1.1 christos value = value >> 1; 706 1.1 christos value++; 707 1.1 christos 708 1.1 christos md_number_to_chars (where - 2, value >> 16, 1); 709 1.1 christos md_number_to_chars (where, value, 1); 710 1.1 christos md_number_to_chars (where + 1, value >> 8, 1); 711 1.1 christos break; 712 1.1 christos 713 1.1 christos case BFD_RELOC_BFIN_5_PCREL: /* LSETUP (a, b) : "a" */ 714 1.1 christos if (!value) 715 1.1 christos break; 716 1.1 christos if (value < 4 || value > 30) 717 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_5")); 718 1.1 christos value = value >> 1; 719 1.1 christos newval = md_chars_to_number (where, 1); 720 1.1 christos newval = (newval & 0xf0) | (value & 0xf); 721 1.1 christos md_number_to_chars (where, newval, 1); 722 1.1 christos break; 723 1.1 christos 724 1.1 christos case BFD_RELOC_BFIN_11_PCREL: /* LSETUP (a, b) : "b" */ 725 1.1 christos if (!value) 726 1.1 christos break; 727 1.1 christos value += 2; 728 1.1 christos if (value < 4 || value > 2046) 729 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_11_PCREL")); 730 1.1 christos /* 11 bit unsigned even, so we remove right bit. */ 731 1.1 christos value = value >> 1; 732 1.1 christos newval = md_chars_to_number (where, 2); 733 1.1 christos newval |= value & 0x03ff; 734 1.1 christos md_number_to_chars (where, newval, 2); 735 1.1 christos break; 736 1.1 christos 737 1.1 christos case BFD_RELOC_8: 738 1.1 christos if (value < -0x80 || value >= 0x7f) 739 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_8")); 740 1.1 christos md_number_to_chars (where, value, 1); 741 1.1 christos break; 742 1.1 christos 743 1.1 christos case BFD_RELOC_BFIN_16_IMM: 744 1.1 christos case BFD_RELOC_16: 745 1.1 christos if (value < -0x8000 || value >= 0x7fff) 746 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_16")); 747 1.1 christos md_number_to_chars (where, value, 2); 748 1.1 christos break; 749 1.1 christos 750 1.1 christos case BFD_RELOC_32: 751 1.1 christos md_number_to_chars (where, value, 4); 752 1.1 christos break; 753 1.1 christos 754 1.1 christos case BFD_RELOC_BFIN_PLTPC: 755 1.1 christos md_number_to_chars (where, value, 2); 756 1.1 christos break; 757 1.1 christos 758 1.1 christos case BFD_RELOC_BFIN_FUNCDESC: 759 1.1 christos case BFD_RELOC_VTABLE_INHERIT: 760 1.1 christos case BFD_RELOC_VTABLE_ENTRY: 761 1.8 christos fixP->fx_done = false; 762 1.1 christos break; 763 1.1 christos 764 1.1 christos default: 765 1.1 christos if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type)) 766 1.1 christos { 767 1.1 christos fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type); 768 1.1 christos return; 769 1.1 christos } 770 1.1 christos } 771 1.1 christos 772 1.1 christos if (!fixP->fx_addsy) 773 1.8 christos fixP->fx_done = true; 774 1.1 christos 775 1.1 christos } 776 1.1 christos 777 1.1 christos /* Round up a section size to the appropriate boundary. */ 778 1.1 christos valueT 779 1.5 christos md_section_align (segT segment, valueT size) 780 1.1 christos { 781 1.7 christos int boundary = bfd_section_alignment (segment); 782 1.3 christos return ((size + (1 << boundary) - 1) & -(1 << boundary)); 783 1.1 christos } 784 1.1 christos 785 1.1 christos 786 1.5 christos const char * 787 1.1 christos md_atof (int type, char * litP, int * sizeP) 788 1.1 christos { 789 1.8 christos return ieee_md_atof (type, litP, sizeP, false); 790 1.1 christos } 791 1.1 christos 792 1.1 christos 793 1.1 christos /* If while processing a fixup, a reloc really needs to be created 794 1.1 christos then it is done here. */ 795 1.1 christos 796 1.1 christos arelent * 797 1.5 christos tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp) 798 1.1 christos { 799 1.1 christos arelent *reloc; 800 1.1 christos 801 1.10 christos reloc = notes_alloc (sizeof (arelent)); 802 1.10 christos reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *)); 803 1.1 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 804 1.10 christos reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 805 1.1 christos 806 1.1 christos reloc->addend = fixp->fx_offset; 807 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 808 1.1 christos 809 1.10 christos if (reloc->howto == NULL) 810 1.1 christos { 811 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 812 1.1 christos /* xgettext:c-format. */ 813 1.1 christos _("reloc %d not supported by object file format"), 814 1.1 christos (int) fixp->fx_r_type); 815 1.1 christos return NULL; 816 1.1 christos } 817 1.1 christos 818 1.1 christos return reloc; 819 1.1 christos } 820 1.1 christos 821 1.1 christos /* The location from which a PC relative jump should be calculated, 822 1.1 christos given a PC relative reloc. */ 823 1.1 christos 824 1.1 christos long 825 1.5 christos md_pcrel_from_section (fixS *fixP, segT sec) 826 1.1 christos { 827 1.10 christos if (fixP->fx_addsy != NULL 828 1.1 christos && (!S_IS_DEFINED (fixP->fx_addsy) 829 1.1 christos || S_GET_SEGMENT (fixP->fx_addsy) != sec)) 830 1.1 christos { 831 1.1 christos /* The symbol is undefined (or is defined but not in this section). 832 1.1 christos Let the linker figure it out. */ 833 1.1 christos return 0; 834 1.1 christos } 835 1.1 christos return fixP->fx_frag->fr_address + fixP->fx_where; 836 1.1 christos } 837 1.1 christos 838 1.1 christos /* Return true if the fix can be handled by GAS, false if it must 839 1.1 christos be passed through to the linker. */ 840 1.1 christos 841 1.8 christos bool 842 1.1 christos bfin_fix_adjustable (fixS *fixP) 843 1.1 christos { 844 1.1 christos switch (fixP->fx_r_type) 845 1.1 christos { 846 1.1 christos /* Adjust_reloc_syms doesn't know about the GOT. */ 847 1.1 christos case BFD_RELOC_BFIN_GOT: 848 1.1 christos case BFD_RELOC_BFIN_PLTPC: 849 1.1 christos /* We need the symbol name for the VTABLE entries. */ 850 1.1 christos case BFD_RELOC_VTABLE_INHERIT: 851 1.1 christos case BFD_RELOC_VTABLE_ENTRY: 852 1.1 christos return 0; 853 1.1 christos 854 1.1 christos default: 855 1.1 christos return 1; 856 1.1 christos } 857 1.1 christos } 858 1.1 christos 859 1.1 christos /* Special extra functions that help bfin-parse.y perform its job. */ 860 1.1 christos 861 1.1 christos struct obstack mempool; 862 1.1 christos 863 1.1 christos INSTR_T 864 1.1 christos conscode (INSTR_T head, INSTR_T tail) 865 1.1 christos { 866 1.1 christos if (!head) 867 1.1 christos return tail; 868 1.1 christos head->next = tail; 869 1.1 christos return head; 870 1.1 christos } 871 1.1 christos 872 1.1 christos INSTR_T 873 1.1 christos conctcode (INSTR_T head, INSTR_T tail) 874 1.1 christos { 875 1.1 christos INSTR_T temp = (head); 876 1.1 christos if (!head) 877 1.1 christos return tail; 878 1.1 christos while (temp->next) 879 1.1 christos temp = temp->next; 880 1.1 christos temp->next = tail; 881 1.1 christos 882 1.1 christos return head; 883 1.1 christos } 884 1.1 christos 885 1.1 christos INSTR_T 886 1.1 christos note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel) 887 1.1 christos { 888 1.1 christos /* Assert that the symbol is not an operator. */ 889 1.1 christos gas_assert (symbol->type == Expr_Node_Reloc); 890 1.1 christos 891 1.1 christos return note_reloc1 (code, symbol->value.s_value, reloc, pcrel); 892 1.1 christos 893 1.1 christos } 894 1.1 christos 895 1.1 christos INSTR_T 896 1.1 christos note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel) 897 1.1 christos { 898 1.1 christos code->reloc = reloc; 899 1.1 christos code->exp = mkexpr (0, symbol_find_or_make (symbol)); 900 1.1 christos code->pcrel = pcrel; 901 1.1 christos return code; 902 1.1 christos } 903 1.1 christos 904 1.1 christos INSTR_T 905 1.1 christos note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel) 906 1.1 christos { 907 1.1 christos code->reloc = reloc; 908 1.1 christos code->exp = mkexpr (value, symbol_find_or_make (symbol)); 909 1.1 christos code->pcrel = pcrel; 910 1.1 christos return code; 911 1.1 christos } 912 1.1 christos 913 1.1 christos INSTR_T 914 1.1 christos gencode (unsigned long x) 915 1.1 christos { 916 1.5 christos INSTR_T cell = XOBNEW (&mempool, struct bfin_insn); 917 1.1 christos memset (cell, 0, sizeof (struct bfin_insn)); 918 1.1 christos cell->value = (x); 919 1.1 christos return cell; 920 1.1 christos } 921 1.1 christos 922 1.1 christos int reloc; 923 1.1 christos int ninsns; 924 1.1 christos int count_insns; 925 1.1 christos 926 1.1 christos static void * 927 1.3 christos allocate (size_t n) 928 1.1 christos { 929 1.1 christos return obstack_alloc (&mempool, n); 930 1.1 christos } 931 1.1 christos 932 1.1 christos Expr_Node * 933 1.1 christos Expr_Node_Create (Expr_Node_Type type, 934 1.1 christos Expr_Node_Value value, 935 1.1 christos Expr_Node *Left_Child, 936 1.1 christos Expr_Node *Right_Child) 937 1.1 christos { 938 1.1 christos 939 1.1 christos 940 1.10 christos Expr_Node *node = allocate (sizeof (Expr_Node)); 941 1.1 christos node->type = type; 942 1.1 christos node->value = value; 943 1.1 christos node->Left_Child = Left_Child; 944 1.1 christos node->Right_Child = Right_Child; 945 1.1 christos return node; 946 1.1 christos } 947 1.1 christos 948 1.1 christos static const char *con = ".__constant"; 949 1.1 christos static const char *op = ".__operator"; 950 1.1 christos static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head); 951 1.1 christos INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc); 952 1.1 christos 953 1.1 christos INSTR_T 954 1.1 christos Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc) 955 1.1 christos { 956 1.6 christos /* Top level relocation expression generator VDSP style. 957 1.1 christos If the relocation is just by itself, generate one item 958 1.1 christos else generate this convoluted expression. */ 959 1.1 christos 960 1.1 christos INSTR_T note = NULL_CODE; 961 1.1 christos INSTR_T note1 = NULL_CODE; 962 1.6 christos int pcrel = 1; /* Is the parent reloc pc-relative? 963 1.1 christos This calculation here and HOWTO should match. */ 964 1.1 christos 965 1.1 christos if (parent_reloc) 966 1.1 christos { 967 1.1 christos /* If it's 32 bit quantity then 16bit code needs to be added. */ 968 1.1 christos int value = 0; 969 1.1 christos 970 1.1 christos if (head->type == Expr_Node_Constant) 971 1.1 christos { 972 1.1 christos /* If note1 is not null code, we have to generate a right 973 1.1 christos aligned value for the constant. Otherwise the reloc is 974 1.1 christos a part of the basic command and the yacc file 975 1.1 christos generates this. */ 976 1.1 christos value = head->value.i_value; 977 1.1 christos } 978 1.1 christos switch (parent_reloc) 979 1.1 christos { 980 1.1 christos /* Some relocations will need to allocate extra words. */ 981 1.1 christos case BFD_RELOC_BFIN_16_IMM: 982 1.1 christos case BFD_RELOC_BFIN_16_LOW: 983 1.1 christos case BFD_RELOC_BFIN_16_HIGH: 984 1.1 christos note1 = conscode (gencode (value), NULL_CODE); 985 1.1 christos pcrel = 0; 986 1.1 christos break; 987 1.1 christos case BFD_RELOC_BFIN_PLTPC: 988 1.1 christos note1 = conscode (gencode (value), NULL_CODE); 989 1.1 christos pcrel = 0; 990 1.1 christos break; 991 1.1 christos case BFD_RELOC_16: 992 1.1 christos case BFD_RELOC_BFIN_GOT: 993 1.1 christos case BFD_RELOC_BFIN_GOT17M4: 994 1.1 christos case BFD_RELOC_BFIN_FUNCDESC_GOT17M4: 995 1.1 christos note1 = conscode (gencode (value), NULL_CODE); 996 1.1 christos pcrel = 0; 997 1.1 christos break; 998 1.1 christos case BFD_RELOC_24_PCREL: 999 1.1 christos case BFD_RELOC_BFIN_24_PCREL_JUMP_L: 1000 1.1 christos case BFD_RELOC_BFIN_24_PCREL_CALL_X: 1001 1.1 christos /* These offsets are even numbered pcrel. */ 1002 1.1 christos note1 = conscode (gencode (value >> 1), NULL_CODE); 1003 1.1 christos break; 1004 1.1 christos default: 1005 1.1 christos note1 = NULL_CODE; 1006 1.1 christos } 1007 1.1 christos } 1008 1.1 christos if (head->type == Expr_Node_Constant) 1009 1.1 christos note = note1; 1010 1.1 christos else if (head->type == Expr_Node_Reloc) 1011 1.1 christos { 1012 1.1 christos note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel); 1013 1.1 christos if (note1 != NULL_CODE) 1014 1.1 christos note = conscode (note1, note); 1015 1.1 christos } 1016 1.1 christos else if (head->type == Expr_Node_Binop 1017 1.1 christos && (head->value.op_value == Expr_Op_Type_Add 1018 1.1 christos || head->value.op_value == Expr_Op_Type_Sub) 1019 1.1 christos && head->Left_Child->type == Expr_Node_Reloc 1020 1.1 christos && head->Right_Child->type == Expr_Node_Constant) 1021 1.1 christos { 1022 1.1 christos int val = head->Right_Child->value.i_value; 1023 1.1 christos if (head->value.op_value == Expr_Op_Type_Sub) 1024 1.1 christos val = -val; 1025 1.1 christos note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value, 1026 1.1 christos parent_reloc, val, 0), 1027 1.1 christos NULL_CODE); 1028 1.1 christos if (note1 != NULL_CODE) 1029 1.1 christos note = conscode (note1, note); 1030 1.1 christos } 1031 1.1 christos else 1032 1.1 christos { 1033 1.1 christos /* Call the recursive function. */ 1034 1.1 christos note = note_reloc1 (gencode (0), op, parent_reloc, pcrel); 1035 1.1 christos if (note1 != NULL_CODE) 1036 1.1 christos note = conscode (note1, note); 1037 1.1 christos note = conctcode (Expr_Node_Gen_Reloc_R (head), note); 1038 1.1 christos } 1039 1.1 christos return note; 1040 1.1 christos } 1041 1.1 christos 1042 1.1 christos static INSTR_T 1043 1.1 christos Expr_Node_Gen_Reloc_R (Expr_Node * head) 1044 1.1 christos { 1045 1.1 christos 1046 1.1 christos INSTR_T note = 0; 1047 1.1 christos INSTR_T note1 = 0; 1048 1.1 christos 1049 1.1 christos switch (head->type) 1050 1.1 christos { 1051 1.1 christos case Expr_Node_Constant: 1052 1.1 christos note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE); 1053 1.1 christos break; 1054 1.1 christos case Expr_Node_Reloc: 1055 1.1 christos note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE); 1056 1.1 christos break; 1057 1.1 christos case Expr_Node_Binop: 1058 1.1 christos note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child)); 1059 1.1 christos switch (head->value.op_value) 1060 1.1 christos { 1061 1.1 christos case Expr_Op_Type_Add: 1062 1.1 christos note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE)); 1063 1.1 christos break; 1064 1.1 christos case Expr_Op_Type_Sub: 1065 1.1 christos note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE)); 1066 1.1 christos break; 1067 1.1 christos case Expr_Op_Type_Mult: 1068 1.1 christos note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE)); 1069 1.1 christos break; 1070 1.1 christos case Expr_Op_Type_Div: 1071 1.1 christos note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE)); 1072 1.1 christos break; 1073 1.1 christos case Expr_Op_Type_Mod: 1074 1.1 christos note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE)); 1075 1.1 christos break; 1076 1.1 christos case Expr_Op_Type_Lshift: 1077 1.1 christos note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE)); 1078 1.1 christos break; 1079 1.1 christos case Expr_Op_Type_Rshift: 1080 1.1 christos note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE)); 1081 1.1 christos break; 1082 1.1 christos case Expr_Op_Type_BAND: 1083 1.1 christos note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE)); 1084 1.1 christos break; 1085 1.1 christos case Expr_Op_Type_BOR: 1086 1.1 christos note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE)); 1087 1.1 christos break; 1088 1.1 christos case Expr_Op_Type_BXOR: 1089 1.1 christos note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE)); 1090 1.1 christos break; 1091 1.1 christos case Expr_Op_Type_LAND: 1092 1.1 christos note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE)); 1093 1.1 christos break; 1094 1.1 christos case Expr_Op_Type_LOR: 1095 1.1 christos note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE)); 1096 1.1 christos break; 1097 1.1 christos default: 1098 1.1 christos fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__); 1099 1.1 christos 1100 1.1 christos 1101 1.1 christos } 1102 1.1 christos break; 1103 1.1 christos case Expr_Node_Unop: 1104 1.1 christos note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE); 1105 1.1 christos switch (head->value.op_value) 1106 1.1 christos { 1107 1.1 christos case Expr_Op_Type_NEG: 1108 1.1 christos note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE)); 1109 1.1 christos break; 1110 1.1 christos case Expr_Op_Type_COMP: 1111 1.1 christos note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE)); 1112 1.1 christos break; 1113 1.1 christos default: 1114 1.1 christos fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__); 1115 1.1 christos } 1116 1.1 christos break; 1117 1.1 christos default: 1118 1.1 christos fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__); 1119 1.1 christos } 1120 1.1 christos return note; 1121 1.1 christos } 1122 1.1 christos 1123 1.1 christos /* Blackfin opcode generation. */ 1125 1.1 christos 1126 1.1 christos /* These functions are called by the generated parser 1127 1.1 christos (from bfin-parse.y), the register type classification 1128 1.1 christos happens in bfin-lex.l. */ 1129 1.1 christos 1130 1.1 christos #include "bfin-aux.h" 1131 1.1 christos #include "opcode/bfin.h" 1132 1.1 christos 1133 1.1 christos #define INIT(t) t c_code = init_##t 1134 1.1 christos #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x) 1135 1.1 christos #define ASSIGNF(x,f) c_code.opcode |= ((x & c_code.mask_##f)<<c_code.bits_##f) 1136 1.1 christos #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x) 1137 1.1 christos 1138 1.1 christos #define HI(x) ((x >> 16) & 0xffff) 1139 1.1 christos #define LO(x) ((x ) & 0xffff) 1140 1.1 christos 1141 1.1 christos #define GROUP(x) ((x->regno & CLASS_MASK) >> 4) 1142 1.1 christos 1143 1.1 christos #define GEN_OPCODE32() \ 1144 1.1 christos conscode (gencode (HI (c_code.opcode)), \ 1145 1.1 christos conscode (gencode (LO (c_code.opcode)), NULL_CODE)) 1146 1.1 christos 1147 1.1 christos #define GEN_OPCODE16() \ 1148 1.1 christos conscode (gencode (c_code.opcode), NULL_CODE) 1149 1.1 christos 1150 1.1 christos 1151 1.1 christos /* 32 BIT INSTRUCTIONS. */ 1152 1.1 christos 1153 1.1 christos 1154 1.1 christos /* DSP32 instruction generation. */ 1155 1.1 christos 1156 1.1 christos INSTR_T 1157 1.1 christos bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P, 1158 1.1 christos int h01, int h11, int h00, int h10, int op0, 1159 1.1 christos REG_T dst, REG_T src0, REG_T src1, int w0) 1160 1.1 christos { 1161 1.1 christos INIT (DSP32Mac); 1162 1.1 christos 1163 1.1 christos ASSIGN (op0); 1164 1.1 christos ASSIGN (op1); 1165 1.1 christos ASSIGN (MM); 1166 1.1 christos ASSIGN (mmod); 1167 1.1 christos ASSIGN (w0); 1168 1.1 christos ASSIGN (w1); 1169 1.1 christos ASSIGN (h01); 1170 1.1 christos ASSIGN (h11); 1171 1.1 christos ASSIGN (h00); 1172 1.1 christos ASSIGN (h10); 1173 1.1 christos ASSIGN (P); 1174 1.1 christos 1175 1.1 christos /* If we have full reg assignments, mask out LSB to encode 1176 1.1 christos single or simultaneous even/odd register moves. */ 1177 1.1 christos if (P) 1178 1.1 christos { 1179 1.1 christos dst->regno &= 0x06; 1180 1.1 christos } 1181 1.1 christos 1182 1.1 christos ASSIGN_R (dst); 1183 1.1 christos ASSIGN_R (src0); 1184 1.1 christos ASSIGN_R (src1); 1185 1.1 christos 1186 1.1 christos return GEN_OPCODE32 (); 1187 1.1 christos } 1188 1.1 christos 1189 1.1 christos INSTR_T 1190 1.1 christos bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P, 1191 1.1 christos int h01, int h11, int h00, int h10, int op0, 1192 1.1 christos REG_T dst, REG_T src0, REG_T src1, int w0) 1193 1.1 christos { 1194 1.1 christos INIT (DSP32Mult); 1195 1.1 christos 1196 1.1 christos ASSIGN (op0); 1197 1.1 christos ASSIGN (op1); 1198 1.1 christos ASSIGN (MM); 1199 1.1 christos ASSIGN (mmod); 1200 1.1 christos ASSIGN (w0); 1201 1.1 christos ASSIGN (w1); 1202 1.1 christos ASSIGN (h01); 1203 1.1 christos ASSIGN (h11); 1204 1.1 christos ASSIGN (h00); 1205 1.1 christos ASSIGN (h10); 1206 1.1 christos ASSIGN (P); 1207 1.1 christos 1208 1.1 christos if (P) 1209 1.1 christos { 1210 1.1 christos dst->regno &= 0x06; 1211 1.1 christos } 1212 1.1 christos 1213 1.1 christos ASSIGN_R (dst); 1214 1.1 christos ASSIGN_R (src0); 1215 1.1 christos ASSIGN_R (src1); 1216 1.1 christos 1217 1.1 christos return GEN_OPCODE32 (); 1218 1.1 christos } 1219 1.1 christos 1220 1.1 christos INSTR_T 1221 1.1 christos bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x, 1222 1.1 christos REG_T dst0, REG_T dst1, REG_T src0, REG_T src1) 1223 1.1 christos { 1224 1.1 christos INIT (DSP32Alu); 1225 1.1 christos 1226 1.1 christos ASSIGN (HL); 1227 1.1 christos ASSIGN (aopcde); 1228 1.1 christos ASSIGN (aop); 1229 1.1 christos ASSIGN (s); 1230 1.1 christos ASSIGN (x); 1231 1.1 christos ASSIGN_R (dst0); 1232 1.1 christos ASSIGN_R (dst1); 1233 1.1 christos ASSIGN_R (src0); 1234 1.1 christos ASSIGN_R (src1); 1235 1.1 christos 1236 1.1 christos return GEN_OPCODE32 (); 1237 1.1 christos } 1238 1.1 christos 1239 1.1 christos INSTR_T 1240 1.1 christos bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0, 1241 1.1 christos REG_T src1, int sop, int HLs) 1242 1.1 christos { 1243 1.1 christos INIT (DSP32Shift); 1244 1.1 christos 1245 1.1 christos ASSIGN (sopcde); 1246 1.1 christos ASSIGN (sop); 1247 1.1 christos ASSIGN (HLs); 1248 1.1 christos 1249 1.1 christos ASSIGN_R (dst0); 1250 1.1 christos ASSIGN_R (src0); 1251 1.1 christos ASSIGN_R (src1); 1252 1.1 christos 1253 1.1 christos return GEN_OPCODE32 (); 1254 1.1 christos } 1255 1.1 christos 1256 1.1 christos INSTR_T 1257 1.1 christos bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag, 1258 1.1 christos REG_T src1, int sop, int HLs) 1259 1.1 christos { 1260 1.1 christos INIT (DSP32ShiftImm); 1261 1.1 christos 1262 1.1 christos ASSIGN (sopcde); 1263 1.1 christos ASSIGN (sop); 1264 1.1 christos ASSIGN (HLs); 1265 1.1 christos 1266 1.1 christos ASSIGN_R (dst0); 1267 1.1 christos ASSIGN (immag); 1268 1.1 christos ASSIGN_R (src1); 1269 1.1 christos 1270 1.1 christos return GEN_OPCODE32 (); 1271 1.1 christos } 1272 1.1 christos 1273 1.1 christos /* LOOP SETUP. */ 1274 1.1 christos 1275 1.1 christos INSTR_T 1276 1.1 christos bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop, 1277 1.1 christos Expr_Node * peoffset, REG_T reg) 1278 1.1 christos { 1279 1.1 christos int soffset, eoffset; 1280 1.1 christos INIT (LoopSetup); 1281 1.1 christos 1282 1.1 christos soffset = (EXPR_VALUE (psoffset) >> 1); 1283 1.1 christos ASSIGN (soffset); 1284 1.1 christos eoffset = (EXPR_VALUE (peoffset) >> 1); 1285 1.1 christos ASSIGN (eoffset); 1286 1.1 christos ASSIGN (rop); 1287 1.1 christos ASSIGN_R (c); 1288 1.1 christos ASSIGN_R (reg); 1289 1.1 christos 1290 1.1 christos return 1291 1.1 christos conscode (gencode (HI (c_code.opcode)), 1292 1.1 christos conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL), 1293 1.1 christos conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL)))); 1294 1.1 christos 1295 1.1 christos } 1296 1.1 christos 1297 1.1 christos /* Call, Link. */ 1298 1.1 christos 1299 1.1 christos INSTR_T 1300 1.1 christos bfin_gen_calla (Expr_Node * addr, int S) 1301 1.1 christos { 1302 1.1 christos int val; 1303 1.1 christos int high_val; 1304 1.1 christos int rel = 0; 1305 1.1 christos INIT (CALLa); 1306 1.1 christos 1307 1.1 christos switch(S){ 1308 1.1 christos case 0 : rel = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break; 1309 1.1 christos case 1 : rel = BFD_RELOC_24_PCREL; break; 1310 1.1 christos case 2 : rel = BFD_RELOC_BFIN_PLTPC; break; 1311 1.1 christos default : break; 1312 1.1 christos } 1313 1.1 christos 1314 1.1 christos ASSIGN (S); 1315 1.1 christos 1316 1.1 christos val = EXPR_VALUE (addr) >> 1; 1317 1.1 christos high_val = val >> 16; 1318 1.1 christos 1319 1.1 christos return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)), 1320 1.1 christos Expr_Node_Gen_Reloc (addr, rel)); 1321 1.1 christos } 1322 1.1 christos 1323 1.1 christos INSTR_T 1324 1.1 christos bfin_gen_linkage (int R, int framesize) 1325 1.1 christos { 1326 1.1 christos INIT (Linkage); 1327 1.1 christos 1328 1.1 christos ASSIGN (R); 1329 1.1 christos ASSIGN (framesize); 1330 1.1 christos 1331 1.1 christos return GEN_OPCODE32 (); 1332 1.1 christos } 1333 1.1 christos 1334 1.1 christos 1335 1.1 christos /* Load and Store. */ 1336 1.1 christos 1337 1.1 christos INSTR_T 1338 1.1 christos bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int rel) 1339 1.1 christos { 1340 1.1 christos int grp, hword; 1341 1.1 christos unsigned val = EXPR_VALUE (phword); 1342 1.1 christos INIT (LDIMMhalf); 1343 1.1 christos 1344 1.1 christos ASSIGN (H); 1345 1.1 christos ASSIGN (S); 1346 1.1 christos ASSIGN (Z); 1347 1.1 christos 1348 1.1 christos ASSIGN_R (reg); 1349 1.1 christos grp = (GROUP (reg)); 1350 1.1 christos ASSIGN (grp); 1351 1.1 christos if (rel == 2) 1352 1.1 christos { 1353 1.1 christos return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM)); 1354 1.1 christos } 1355 1.1 christos else if (rel == 1) 1356 1.1 christos { 1357 1.1 christos return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, IS_H (*reg) ? BFD_RELOC_BFIN_16_HIGH : BFD_RELOC_BFIN_16_LOW)); 1358 1.1 christos } 1359 1.1 christos else 1360 1.1 christos { 1361 1.1 christos hword = val; 1362 1.1 christos ASSIGN (hword); 1363 1.1 christos } 1364 1.1 christos return GEN_OPCODE32 (); 1365 1.1 christos } 1366 1.1 christos 1367 1.1 christos INSTR_T 1368 1.1 christos bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset) 1369 1.1 christos { 1370 1.1 christos INIT (LDSTidxI); 1371 1.1 christos 1372 1.1 christos if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z)) 1373 1.1 christos { 1374 1.1 christos fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n"); 1375 1.1 christos return 0; 1376 1.1 christos } 1377 1.1 christos 1378 1.1 christos ASSIGN_R (ptr); 1379 1.1 christos ASSIGN_R (reg); 1380 1.1 christos ASSIGN (W); 1381 1.1 christos ASSIGN (sz); 1382 1.1 christos 1383 1.1 christos ASSIGN (Z); 1384 1.1 christos 1385 1.1 christos if (poffset->type != Expr_Node_Constant) 1386 1.1 christos { 1387 1.1 christos /* a GOT relocation such as R0 = [P5 + symbol@GOT] */ 1388 1.1 christos /* distinguish between R0 = [P5 + symbol@GOT] and 1389 1.1 christos P5 = [P5 + _current_shared_library_p5_offset_] 1390 1.1 christos */ 1391 1.1 christos if (poffset->type == Expr_Node_Reloc 1392 1.1 christos && !strcmp (poffset->value.s_value, 1393 1.1 christos "_current_shared_library_p5_offset_")) 1394 1.1 christos { 1395 1.1 christos return conscode (gencode (HI (c_code.opcode)), 1396 1.1 christos Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16)); 1397 1.1 christos } 1398 1.1 christos else if (poffset->type != Expr_Node_GOT_Reloc) 1399 1.1 christos abort (); 1400 1.1 christos 1401 1.1 christos return conscode (gencode (HI (c_code.opcode)), 1402 1.1 christos Expr_Node_Gen_Reloc(poffset->Left_Child, 1403 1.1 christos poffset->value.i_value)); 1404 1.1 christos } 1405 1.1 christos else 1406 1.1 christos { 1407 1.1 christos int value, offset; 1408 1.1 christos switch (sz) 1409 1.1 christos { /* load/store access size */ 1410 1.1 christos case 0: /* 32 bit */ 1411 1.1 christos value = EXPR_VALUE (poffset) >> 2; 1412 1.1 christos break; 1413 1.1 christos case 1: /* 16 bit */ 1414 1.1 christos value = EXPR_VALUE (poffset) >> 1; 1415 1.1 christos break; 1416 1.1 christos case 2: /* 8 bit */ 1417 1.1 christos value = EXPR_VALUE (poffset); 1418 1.1 christos break; 1419 1.1 christos default: 1420 1.1 christos abort (); 1421 1.1 christos } 1422 1.1 christos 1423 1.1 christos offset = (value & 0xffff); 1424 1.1 christos ASSIGN (offset); 1425 1.1 christos return GEN_OPCODE32 (); 1426 1.1 christos } 1427 1.1 christos } 1428 1.1 christos 1429 1.1 christos 1430 1.1 christos INSTR_T 1431 1.1 christos bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W) 1432 1.1 christos { 1433 1.1 christos INIT (LDST); 1434 1.1 christos 1435 1.1 christos if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z)) 1436 1.1 christos { 1437 1.1 christos fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n"); 1438 1.1 christos return 0; 1439 1.1 christos } 1440 1.1 christos 1441 1.1 christos ASSIGN_R (ptr); 1442 1.1 christos ASSIGN_R (reg); 1443 1.1 christos ASSIGN (aop); 1444 1.1 christos ASSIGN (sz); 1445 1.1 christos ASSIGN (Z); 1446 1.1 christos ASSIGN (W); 1447 1.1 christos 1448 1.1 christos return GEN_OPCODE16 (); 1449 1.1 christos } 1450 1.1 christos 1451 1.1 christos INSTR_T 1452 1.1 christos bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int opc) 1453 1.1 christos { 1454 1.1 christos int offset; 1455 1.1 christos int value = 0; 1456 1.1 christos INIT (LDSTii); 1457 1.1 christos 1458 1.1 christos if (!IS_PREG (*ptr)) 1459 1.1 christos { 1460 1.1 christos fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n"); 1461 1.1 christos return 0; 1462 1.1 christos } 1463 1.1 christos 1464 1.1 christos switch (opc) 1465 1.1 christos { 1466 1.1 christos case 1: 1467 1.1 christos case 2: 1468 1.1 christos value = EXPR_VALUE (poffset) >> 1; 1469 1.1 christos break; 1470 1.1 christos case 0: 1471 1.1 christos case 3: 1472 1.1 christos value = EXPR_VALUE (poffset) >> 2; 1473 1.1 christos break; 1474 1.1 christos } 1475 1.1 christos 1476 1.1 christos ASSIGN_R (ptr); 1477 1.1 christos ASSIGN_R (reg); 1478 1.1 christos 1479 1.1 christos offset = value; 1480 1.1 christos ASSIGN (offset); 1481 1.1 christos ASSIGN (W); 1482 1.1 christos ASSIGNF (opc, op); 1483 1.1 christos 1484 1.1 christos return GEN_OPCODE16 (); 1485 1.1 christos } 1486 1.1 christos 1487 1.1 christos INSTR_T 1488 1.1 christos bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W) 1489 1.1 christos { 1490 1.1 christos /* Set bit 4 if it's a Preg. */ 1491 1.1 christos int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0); 1492 1.1 christos int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1; 1493 1.1 christos INIT (LDSTiiFP); 1494 1.1 christos ASSIGN (reg); 1495 1.1 christos ASSIGN (offset); 1496 1.1 christos ASSIGN (W); 1497 1.1 christos 1498 1.1 christos return GEN_OPCODE16 (); 1499 1.1 christos } 1500 1.1 christos 1501 1.1 christos INSTR_T 1502 1.1 christos bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx) 1503 1.1 christos { 1504 1.1 christos INIT (LDSTpmod); 1505 1.1 christos 1506 1.1 christos ASSIGN_R (ptr); 1507 1.1 christos ASSIGN_R (reg); 1508 1.1 christos ASSIGN (aop); 1509 1.1 christos ASSIGN (W); 1510 1.1 christos ASSIGN_R (idx); 1511 1.1 christos 1512 1.1 christos return GEN_OPCODE16 (); 1513 1.1 christos } 1514 1.1 christos 1515 1.1 christos INSTR_T 1516 1.1 christos bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m) 1517 1.1 christos { 1518 1.1 christos INIT (DspLDST); 1519 1.1 christos 1520 1.1 christos ASSIGN_R (i); 1521 1.1 christos ASSIGN_R (reg); 1522 1.1 christos ASSIGN (aop); 1523 1.1 christos ASSIGN (W); 1524 1.1 christos ASSIGN (m); 1525 1.1 christos 1526 1.1 christos return GEN_OPCODE16 (); 1527 1.1 christos } 1528 1.1 christos 1529 1.1 christos INSTR_T 1530 1.1 christos bfin_gen_logi2op (int opc, int src, int dst) 1531 1.1 christos { 1532 1.1 christos INIT (LOGI2op); 1533 1.1 christos 1534 1.1 christos ASSIGN (opc); 1535 1.1 christos ASSIGN (src); 1536 1.1 christos ASSIGN (dst); 1537 1.1 christos 1538 1.1 christos return GEN_OPCODE16 (); 1539 1.1 christos } 1540 1.1 christos 1541 1.1 christos INSTR_T 1542 1.1 christos bfin_gen_brcc (int T, int B, Expr_Node * poffset) 1543 1.1 christos { 1544 1.1 christos int offset; 1545 1.1 christos INIT (BRCC); 1546 1.1 christos 1547 1.1 christos ASSIGN (T); 1548 1.1 christos ASSIGN (B); 1549 1.1 christos offset = ((EXPR_VALUE (poffset) >> 1)); 1550 1.1 christos ASSIGN (offset); 1551 1.1 christos return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL)); 1552 1.1 christos } 1553 1.1 christos 1554 1.1 christos INSTR_T 1555 1.1 christos bfin_gen_ujump (Expr_Node * poffset) 1556 1.1 christos { 1557 1.1 christos int offset; 1558 1.1 christos INIT (UJump); 1559 1.1 christos 1560 1.1 christos offset = ((EXPR_VALUE (poffset) >> 1)); 1561 1.1 christos ASSIGN (offset); 1562 1.1 christos 1563 1.1 christos return conscode (gencode (c_code.opcode), 1564 1.1 christos Expr_Node_Gen_Reloc ( 1565 1.1 christos poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S)); 1566 1.1 christos } 1567 1.1 christos 1568 1.1 christos INSTR_T 1569 1.1 christos bfin_gen_alu2op (REG_T dst, REG_T src, int opc) 1570 1.1 christos { 1571 1.1 christos INIT (ALU2op); 1572 1.1 christos 1573 1.1 christos ASSIGN_R (dst); 1574 1.1 christos ASSIGN_R (src); 1575 1.1 christos ASSIGN (opc); 1576 1.1 christos 1577 1.1 christos return GEN_OPCODE16 (); 1578 1.1 christos } 1579 1.1 christos 1580 1.1 christos INSTR_T 1581 1.1 christos bfin_gen_compi2opd (REG_T dst, int src, int opc) 1582 1.1 christos { 1583 1.1 christos INIT (COMPI2opD); 1584 1.1 christos 1585 1.1 christos ASSIGN_R (dst); 1586 1.1 christos ASSIGN (src); 1587 1.1 christos ASSIGNF (opc, op); 1588 1.1 christos 1589 1.1 christos return GEN_OPCODE16 (); 1590 1.1 christos } 1591 1.1 christos 1592 1.1 christos INSTR_T 1593 1.1 christos bfin_gen_compi2opp (REG_T dst, int src, int opc) 1594 1.1 christos { 1595 1.1 christos INIT (COMPI2opP); 1596 1.1 christos 1597 1.1 christos ASSIGN_R (dst); 1598 1.1 christos ASSIGN (src); 1599 1.1 christos ASSIGNF (opc, op); 1600 1.1 christos 1601 1.1 christos return GEN_OPCODE16 (); 1602 1.1 christos } 1603 1.1 christos 1604 1.1 christos INSTR_T 1605 1.1 christos bfin_gen_dagmodik (REG_T i, int opc) 1606 1.1 christos { 1607 1.1 christos INIT (DagMODik); 1608 1.1 christos 1609 1.1 christos ASSIGN_R (i); 1610 1.1 christos ASSIGNF (opc, op); 1611 1.1 christos 1612 1.1 christos return GEN_OPCODE16 (); 1613 1.1 christos } 1614 1.1 christos 1615 1.1 christos INSTR_T 1616 1.1 christos bfin_gen_dagmodim (REG_T i, REG_T m, int opc, int br) 1617 1.1 christos { 1618 1.1 christos INIT (DagMODim); 1619 1.1 christos 1620 1.1 christos ASSIGN_R (i); 1621 1.1 christos ASSIGN_R (m); 1622 1.1 christos ASSIGNF (opc, op); 1623 1.1 christos ASSIGN (br); 1624 1.1 christos 1625 1.1 christos return GEN_OPCODE16 (); 1626 1.1 christos } 1627 1.1 christos 1628 1.1 christos INSTR_T 1629 1.1 christos bfin_gen_ptr2op (REG_T dst, REG_T src, int opc) 1630 1.1 christos { 1631 1.1 christos INIT (PTR2op); 1632 1.1 christos 1633 1.1 christos ASSIGN_R (dst); 1634 1.1 christos ASSIGN_R (src); 1635 1.1 christos ASSIGN (opc); 1636 1.1 christos 1637 1.1 christos return GEN_OPCODE16 (); 1638 1.1 christos } 1639 1.1 christos 1640 1.1 christos INSTR_T 1641 1.1 christos bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc) 1642 1.1 christos { 1643 1.1 christos INIT (COMP3op); 1644 1.1 christos 1645 1.1 christos ASSIGN_R (src0); 1646 1.1 christos ASSIGN_R (src1); 1647 1.1 christos ASSIGN_R (dst); 1648 1.1 christos ASSIGN (opc); 1649 1.1 christos 1650 1.1 christos return GEN_OPCODE16 (); 1651 1.1 christos } 1652 1.1 christos 1653 1.1 christos INSTR_T 1654 1.1 christos bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G) 1655 1.1 christos { 1656 1.1 christos INIT (CCflag); 1657 1.1 christos 1658 1.1 christos ASSIGN_R (x); 1659 1.1 christos ASSIGN (y); 1660 1.1 christos ASSIGN (opc); 1661 1.1 christos ASSIGN (I); 1662 1.1 christos ASSIGN (G); 1663 1.1 christos 1664 1.1 christos return GEN_OPCODE16 (); 1665 1.1 christos } 1666 1.1 christos 1667 1.1 christos INSTR_T 1668 1.1 christos bfin_gen_ccmv (REG_T src, REG_T dst, int T) 1669 1.1 christos { 1670 1.1 christos int s, d; 1671 1.1 christos INIT (CCmv); 1672 1.1 christos 1673 1.1 christos ASSIGN_R (src); 1674 1.1 christos ASSIGN_R (dst); 1675 1.1 christos s = (GROUP (src)); 1676 1.1 christos ASSIGN (s); 1677 1.1 christos d = (GROUP (dst)); 1678 1.1 christos ASSIGN (d); 1679 1.1 christos ASSIGN (T); 1680 1.1 christos 1681 1.1 christos return GEN_OPCODE16 (); 1682 1.1 christos } 1683 1.1 christos 1684 1.1 christos INSTR_T 1685 1.1 christos bfin_gen_cc2stat (int cbit, int opc, int D) 1686 1.1 christos { 1687 1.1 christos INIT (CC2stat); 1688 1.1 christos 1689 1.1 christos ASSIGN (cbit); 1690 1.1 christos ASSIGNF (opc, op); 1691 1.1 christos ASSIGN (D); 1692 1.1 christos 1693 1.1 christos return GEN_OPCODE16 (); 1694 1.1 christos } 1695 1.1 christos 1696 1.1 christos INSTR_T 1697 1.1 christos bfin_gen_regmv (REG_T src, REG_T dst) 1698 1.1 christos { 1699 1.1 christos int gs, gd; 1700 1.1 christos INIT (RegMv); 1701 1.1 christos 1702 1.1 christos ASSIGN_R (src); 1703 1.1 christos ASSIGN_R (dst); 1704 1.1 christos 1705 1.1 christos gs = (GROUP (src)); 1706 1.1 christos ASSIGN (gs); 1707 1.1 christos gd = (GROUP (dst)); 1708 1.1 christos ASSIGN (gd); 1709 1.1 christos 1710 1.1 christos return GEN_OPCODE16 (); 1711 1.1 christos } 1712 1.1 christos 1713 1.1 christos INSTR_T 1714 1.1 christos bfin_gen_cc2dreg (int opc, REG_T reg) 1715 1.1 christos { 1716 1.1 christos INIT (CC2dreg); 1717 1.1 christos 1718 1.1 christos ASSIGNF (opc, op); 1719 1.1 christos ASSIGN_R (reg); 1720 1.1 christos 1721 1.1 christos return GEN_OPCODE16 (); 1722 1.1 christos } 1723 1.1 christos 1724 1.1 christos INSTR_T 1725 1.1 christos bfin_gen_progctrl (int prgfunc, int poprnd) 1726 1.1 christos { 1727 1.1 christos INIT (ProgCtrl); 1728 1.1 christos 1729 1.1 christos ASSIGN (prgfunc); 1730 1.1 christos ASSIGN (poprnd); 1731 1.1 christos 1732 1.1 christos return GEN_OPCODE16 (); 1733 1.1 christos } 1734 1.1 christos 1735 1.1 christos INSTR_T 1736 1.1 christos bfin_gen_cactrl (REG_T reg, int a, int opc) 1737 1.1 christos { 1738 1.1 christos INIT (CaCTRL); 1739 1.1 christos 1740 1.1 christos ASSIGN_R (reg); 1741 1.1 christos ASSIGN (a); 1742 1.1 christos ASSIGNF (opc, op); 1743 1.1 christos 1744 1.1 christos return GEN_OPCODE16 (); 1745 1.1 christos } 1746 1.1 christos 1747 1.1 christos INSTR_T 1748 1.1 christos bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W) 1749 1.1 christos { 1750 1.1 christos INIT (PushPopMultiple); 1751 1.1 christos 1752 1.1 christos ASSIGN (dr); 1753 1.1 christos ASSIGN (pr); 1754 1.1 christos ASSIGN (d); 1755 1.1 christos ASSIGN (p); 1756 1.1 christos ASSIGN (W); 1757 1.1 christos 1758 1.1 christos return GEN_OPCODE16 (); 1759 1.1 christos } 1760 1.1 christos 1761 1.1 christos INSTR_T 1762 1.1 christos bfin_gen_pushpopreg (REG_T reg, int W) 1763 1.1 christos { 1764 1.1 christos int grp; 1765 1.1 christos INIT (PushPopReg); 1766 1.1 christos 1767 1.1 christos ASSIGN_R (reg); 1768 1.1 christos grp = (GROUP (reg)); 1769 1.1 christos ASSIGN (grp); 1770 1.1 christos ASSIGN (W); 1771 1.1 christos 1772 1.1 christos return GEN_OPCODE16 (); 1773 1.1 christos } 1774 1.1 christos 1775 1.1 christos /* Pseudo Debugging Support. */ 1776 1.1 christos 1777 1.1 christos INSTR_T 1778 1.1 christos bfin_gen_pseudodbg (int fn, int reg, int grp) 1779 1.1 christos { 1780 1.1 christos INIT (PseudoDbg); 1781 1.1 christos 1782 1.1 christos ASSIGN (fn); 1783 1.1 christos ASSIGN (reg); 1784 1.1 christos ASSIGN (grp); 1785 1.1 christos 1786 1.1 christos return GEN_OPCODE16 (); 1787 1.1 christos } 1788 1.1 christos 1789 1.1 christos INSTR_T 1790 1.1 christos bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected) 1791 1.1 christos { 1792 1.1 christos int grp; 1793 1.1 christos INIT (PseudoDbg_Assert); 1794 1.1 christos 1795 1.1 christos ASSIGN (dbgop); 1796 1.1 christos ASSIGN_R (regtest); 1797 1.1 christos grp = GROUP (regtest); 1798 1.1 christos ASSIGN (grp); 1799 1.1 christos ASSIGN (expected); 1800 1.1 christos 1801 1.1 christos return GEN_OPCODE32 (); 1802 1.1 christos } 1803 1.1 christos 1804 1.1 christos INSTR_T 1805 1.1 christos bfin_gen_pseudochr (int ch) 1806 1.1 christos { 1807 1.1 christos INIT (PseudoChr); 1808 1.1 christos 1809 1.1 christos ASSIGN (ch); 1810 1.1 christos 1811 1.1 christos return GEN_OPCODE16 (); 1812 1.1 christos } 1813 1.1 christos 1814 1.1 christos /* Multiple instruction generation. */ 1815 1.1 christos 1816 1.1 christos INSTR_T 1817 1.1 christos bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2) 1818 1.1 christos { 1819 1.1 christos INSTR_T walk; 1820 1.1 christos 1821 1.1 christos /* If it's a 0, convert into MNOP. */ 1822 1.1 christos if (dsp32) 1823 1.1 christos { 1824 1.1 christos walk = dsp32->next; 1825 1.1 christos SET_MULTI_INSTRUCTION_BIT (dsp32); 1826 1.1 christos } 1827 1.1 christos else 1828 1.1 christos { 1829 1.1 christos dsp32 = gencode (0xc803); 1830 1.1 christos walk = gencode (0x1800); 1831 1.1 christos dsp32->next = walk; 1832 1.1 christos } 1833 1.1 christos 1834 1.1 christos if (!dsp16_grp1) 1835 1.1 christos { 1836 1.1 christos dsp16_grp1 = gencode (0x0000); 1837 1.1 christos } 1838 1.1 christos 1839 1.1 christos if (!dsp16_grp2) 1840 1.1 christos { 1841 1.1 christos dsp16_grp2 = gencode (0x0000); 1842 1.1 christos } 1843 1.1 christos 1844 1.1 christos walk->next = dsp16_grp1; 1845 1.1 christos dsp16_grp1->next = dsp16_grp2; 1846 1.1 christos dsp16_grp2->next = NULL_CODE; 1847 1.1 christos 1848 1.1 christos return dsp32; 1849 1.1 christos } 1850 1.1 christos 1851 1.1 christos INSTR_T 1852 1.1 christos bfin_gen_loop (Expr_Node *exp, REG_T reg, int rop, REG_T preg) 1853 1.1 christos { 1854 1.1 christos const char *loopsym; 1855 1.1 christos char *lbeginsym, *lendsym; 1856 1.1 christos Expr_Node_Value lbeginval, lendval; 1857 1.1 christos Expr_Node *lbegin, *lend; 1858 1.1 christos symbolS *sym; 1859 1.1 christos 1860 1.10 christos loopsym = exp->value.s_value; 1861 1.10 christos lbeginsym = xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 5); 1862 1.1 christos lendsym = xmalloc (strlen (loopsym) + strlen ("__END") + 5); 1863 1.1 christos 1864 1.1 christos lbeginsym[0] = 0; 1865 1.1 christos lendsym[0] = 0; 1866 1.1 christos 1867 1.1 christos strcat (lbeginsym, "L$L$"); 1868 1.1 christos strcat (lbeginsym, loopsym); 1869 1.1 christos strcat (lbeginsym, "__BEGIN"); 1870 1.1 christos 1871 1.1 christos strcat (lendsym, "L$L$"); 1872 1.1 christos strcat (lendsym, loopsym); 1873 1.1 christos strcat (lendsym, "__END"); 1874 1.1 christos 1875 1.1 christos lbeginval.s_value = lbeginsym; 1876 1.1 christos lendval.s_value = lendsym; 1877 1.1 christos 1878 1.1 christos lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL); 1879 1.1 christos lend = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL); 1880 1.1 christos 1881 1.1 christos sym = symbol_find(loopsym); 1882 1.1 christos if (!S_IS_LOCAL (sym) || (S_IS_LOCAL (sym) && !symbol_used_p (sym))) 1883 1.1 christos symbol_remove (sym, &symbol_rootP, &symbol_lastP); 1884 1.1 christos 1885 1.1 christos return bfin_gen_loopsetup (lbegin, reg, rop, lend, preg); 1886 1.1 christos } 1887 1.1 christos 1888 1.1 christos void 1889 1.1 christos bfin_loop_attempt_create_label (Expr_Node *exp, int is_begin) 1890 1.1 christos { 1891 1.1 christos char *name; 1892 1.1 christos name = fb_label_name (exp->value.i_value, is_begin); 1893 1.1 christos exp->value.s_value = xstrdup (name); 1894 1.1 christos exp->type = Expr_Node_Reloc; 1895 1.1 christos } 1896 1.1 christos 1897 1.1 christos void 1898 1.1 christos bfin_loop_beginend (Expr_Node *exp, int begin) 1899 1.1 christos { 1900 1.1 christos const char *loopsym; 1901 1.1 christos char *label_name; 1902 1.1 christos symbolS *linelabel; 1903 1.1 christos const char *suffix = begin ? "__BEGIN" : "__END"; 1904 1.1 christos 1905 1.10 christos loopsym = exp->value.s_value; 1906 1.1 christos label_name = xmalloc (strlen (loopsym) + strlen (suffix) + 5); 1907 1.1 christos 1908 1.1 christos label_name[0] = 0; 1909 1.1 christos 1910 1.1 christos strcat (label_name, "L$L$"); 1911 1.1 christos strcat (label_name, loopsym); 1912 1.1 christos strcat (label_name, suffix); 1913 1.1 christos 1914 1.1 christos linelabel = colon (label_name); 1915 1.1 christos 1916 1.1 christos /* LOOP_END follows the last instruction in the loop. 1917 1.1 christos Adjust label address. */ 1918 1.7 christos if (!begin) 1919 1.10 christos *symbol_X_add_number (linelabel) -= last_insn_size; 1920 1.10 christos 1921 1.1 christos free (label_name); 1922 1.1 christos } 1923 1.8 christos 1924 1.1 christos bool 1925 1.1 christos bfin_eol_in_insn (char *line) 1926 1.1 christos { 1927 1.1 christos /* Allow a new-line to appear in the middle of a multi-issue instruction. */ 1928 1.1 christos 1929 1.1 christos char *temp = line; 1930 1.1 christos 1931 1.8 christos if (*line != '\n') 1932 1.1 christos return false; 1933 1.1 christos 1934 1.1 christos /* A semi-colon followed by a newline is always the end of a line. */ 1935 1.8 christos if (line[-1] == ';') 1936 1.1 christos return false; 1937 1.1 christos 1938 1.8 christos if (line[-1] == '|') 1939 1.1 christos return true; 1940 1.1 christos 1941 1.1 christos /* If the || is on the next line, there might be leading whitespace. */ 1942 1.10 christos temp++; 1943 1.10 christos while (is_whitespace (*temp)) 1944 1.1 christos temp++; 1945 1.1 christos 1946 1.8 christos if (*temp == '|') 1947 1.1 christos return true; 1948 1.8 christos 1949 1.1 christos return false; 1950 1.1 christos } 1951 1.8 christos 1952 1.3 christos bool 1953 1.1 christos bfin_start_label (char *s) 1954 1.3 christos { 1955 1.1 christos while (*s != 0) 1956 1.1 christos { 1957 1.8 christos if (*s == '(' || *s == '[') 1958 1.1 christos return false; 1959 1.1 christos s++; 1960 1.1 christos } 1961 1.8 christos 1962 1.1 christos return true; 1963 1.1 christos } 1964 1.1 christos 1965 1.1 christos int 1966 1.1 christos bfin_force_relocation (struct fix *fixp) 1967 1.1 christos { 1968 1.1 christos if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW 1969 1.8 christos || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH) 1970 1.1 christos return true; 1971 1.1 christos 1972 1.1 christos return generic_force_reloc (fixp); 1973 1.1 christos } 1974 1.1 christos 1975 1.1 christos /* This is a stripped down version of the disassembler. The only thing it 1977 1.1 christos does is return a mask of registers modified by an instruction. Only 1978 1.1 christos instructions that can occur in a parallel-issue bundle are handled, and 1979 1.1 christos only the registers that can cause a conflict are recorded. */ 1980 1.1 christos 1981 1.1 christos #define DREG_MASK(n) (0x101 << (n)) 1982 1.1 christos #define DREGH_MASK(n) (0x100 << (n)) 1983 1.1 christos #define DREGL_MASK(n) (0x001 << (n)) 1984 1.1 christos #define IREG_MASK(n) (1 << ((n) + 16)) 1985 1.1 christos 1986 1.1 christos static int 1987 1.1 christos decode_ProgCtrl_0 (int iw0) 1988 1.1 christos { 1989 1.1 christos if (iw0 == 0) 1990 1.1 christos return 0; 1991 1.1 christos abort (); 1992 1.1 christos } 1993 1.1 christos 1994 1.1 christos static int 1995 1.1 christos decode_LDSTpmod_0 (int iw0) 1996 1.1 christos { 1997 1.1 christos /* LDSTpmod 1998 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 1999 1.1 christos | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......| 2000 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2001 1.1 christos int W = ((iw0 >> LDSTpmod_W_bits) & LDSTpmod_W_mask); 2002 1.1 christos int aop = ((iw0 >> LDSTpmod_aop_bits) & LDSTpmod_aop_mask); 2003 1.1 christos int idx = ((iw0 >> LDSTpmod_idx_bits) & LDSTpmod_idx_mask); 2004 1.1 christos int ptr = ((iw0 >> LDSTpmod_ptr_bits) & LDSTpmod_ptr_mask); 2005 1.1 christos int reg = ((iw0 >> LDSTpmod_reg_bits) & LDSTpmod_reg_mask); 2006 1.1 christos 2007 1.1 christos if (aop == 1 && W == 0 && idx == ptr) 2008 1.1 christos return DREGL_MASK (reg); 2009 1.1 christos else if (aop == 2 && W == 0 && idx == ptr) 2010 1.1 christos return DREGH_MASK (reg); 2011 1.1 christos else if (aop == 1 && W == 1 && idx == ptr) 2012 1.1 christos return 0; 2013 1.1 christos else if (aop == 2 && W == 1 && idx == ptr) 2014 1.1 christos return 0; 2015 1.1 christos else if (aop == 0 && W == 0) 2016 1.1 christos return DREG_MASK (reg); 2017 1.1 christos else if (aop == 1 && W == 0) 2018 1.1 christos return DREGL_MASK (reg); 2019 1.1 christos else if (aop == 2 && W == 0) 2020 1.1 christos return DREGH_MASK (reg); 2021 1.1 christos else if (aop == 3 && W == 0) 2022 1.1 christos return DREG_MASK (reg); 2023 1.1 christos else if (aop == 3 && W == 1) 2024 1.1 christos return DREG_MASK (reg); 2025 1.1 christos else if (aop == 0 && W == 1) 2026 1.1 christos return 0; 2027 1.1 christos else if (aop == 1 && W == 1) 2028 1.1 christos return 0; 2029 1.1 christos else if (aop == 2 && W == 1) 2030 1.1 christos return 0; 2031 1.1 christos else 2032 1.1 christos return 0; 2033 1.1 christos 2034 1.1 christos return 2; 2035 1.1 christos } 2036 1.1 christos 2037 1.1 christos static int 2038 1.1 christos decode_dagMODim_0 (int iw0) 2039 1.1 christos { 2040 1.1 christos /* dagMODim 2041 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2042 1.1 christos | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....| 2043 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2044 1.1 christos int i = ((iw0 >> DagMODim_i_bits) & DagMODim_i_mask); 2045 1.1 christos int opc = ((iw0 >> DagMODim_op_bits) & DagMODim_op_mask); 2046 1.1 christos 2047 1.1 christos if (opc == 0 || opc == 1) 2048 1.1 christos return IREG_MASK (i); 2049 1.1 christos else 2050 1.1 christos return 0; 2051 1.1 christos 2052 1.1 christos return 2; 2053 1.1 christos } 2054 1.1 christos 2055 1.1 christos static int 2056 1.1 christos decode_dagMODik_0 (int iw0) 2057 1.1 christos { 2058 1.1 christos /* dagMODik 2059 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2060 1.1 christos | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....| 2061 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2062 1.1 christos int i = ((iw0 >> DagMODik_i_bits) & DagMODik_i_mask); 2063 1.1 christos return IREG_MASK (i); 2064 1.1 christos } 2065 1.1 christos 2066 1.1 christos /* GOOD */ 2067 1.1 christos static int 2068 1.1 christos decode_dspLDST_0 (int iw0) 2069 1.1 christos { 2070 1.1 christos /* dspLDST 2071 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2072 1.1 christos | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......| 2073 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2074 1.1 christos int i = ((iw0 >> DspLDST_i_bits) & DspLDST_i_mask); 2075 1.1 christos int m = ((iw0 >> DspLDST_m_bits) & DspLDST_m_mask); 2076 1.1 christos int W = ((iw0 >> DspLDST_W_bits) & DspLDST_W_mask); 2077 1.1 christos int aop = ((iw0 >> DspLDST_aop_bits) & DspLDST_aop_mask); 2078 1.1 christos int reg = ((iw0 >> DspLDST_reg_bits) & DspLDST_reg_mask); 2079 1.1 christos 2080 1.1 christos if (aop == 0 && W == 0 && m == 0) 2081 1.1 christos return DREG_MASK (reg) | IREG_MASK (i); 2082 1.1 christos else if (aop == 0 && W == 0 && m == 1) 2083 1.1 christos return DREGL_MASK (reg) | IREG_MASK (i); 2084 1.1 christos else if (aop == 0 && W == 0 && m == 2) 2085 1.1 christos return DREGH_MASK (reg) | IREG_MASK (i); 2086 1.1 christos else if (aop == 1 && W == 0 && m == 0) 2087 1.1 christos return DREG_MASK (reg) | IREG_MASK (i); 2088 1.1 christos else if (aop == 1 && W == 0 && m == 1) 2089 1.1 christos return DREGL_MASK (reg) | IREG_MASK (i); 2090 1.1 christos else if (aop == 1 && W == 0 && m == 2) 2091 1.1 christos return DREGH_MASK (reg) | IREG_MASK (i); 2092 1.1 christos else if (aop == 2 && W == 0 && m == 0) 2093 1.1 christos return DREG_MASK (reg); 2094 1.1 christos else if (aop == 2 && W == 0 && m == 1) 2095 1.1 christos return DREGL_MASK (reg); 2096 1.1 christos else if (aop == 2 && W == 0 && m == 2) 2097 1.1 christos return DREGH_MASK (reg); 2098 1.1 christos else if (aop == 0 && W == 1 && m == 0) 2099 1.1 christos return IREG_MASK (i); 2100 1.1 christos else if (aop == 0 && W == 1 && m == 1) 2101 1.1 christos return IREG_MASK (i); 2102 1.1 christos else if (aop == 0 && W == 1 && m == 2) 2103 1.1 christos return IREG_MASK (i); 2104 1.1 christos else if (aop == 1 && W == 1 && m == 0) 2105 1.1 christos return IREG_MASK (i); 2106 1.1 christos else if (aop == 1 && W == 1 && m == 1) 2107 1.1 christos return IREG_MASK (i); 2108 1.1 christos else if (aop == 1 && W == 1 && m == 2) 2109 1.1 christos return IREG_MASK (i); 2110 1.1 christos else if (aop == 2 && W == 1 && m == 0) 2111 1.1 christos return 0; 2112 1.1 christos else if (aop == 2 && W == 1 && m == 1) 2113 1.1 christos return 0; 2114 1.1 christos else if (aop == 2 && W == 1 && m == 2) 2115 1.1 christos return 0; 2116 1.1 christos else if (aop == 3 && W == 0) 2117 1.1 christos return DREG_MASK (reg) | IREG_MASK (i); 2118 1.1 christos else if (aop == 3 && W == 1) 2119 1.1 christos return IREG_MASK (i); 2120 1.1 christos 2121 1.1 christos abort (); 2122 1.1 christos } 2123 1.1 christos 2124 1.1 christos /* GOOD */ 2125 1.1 christos static int 2126 1.1 christos decode_LDST_0 (int iw0) 2127 1.1 christos { 2128 1.1 christos /* LDST 2129 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2130 1.1 christos | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......| 2131 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2132 1.1 christos int Z = ((iw0 >> LDST_Z_bits) & LDST_Z_mask); 2133 1.1 christos int W = ((iw0 >> LDST_W_bits) & LDST_W_mask); 2134 1.1 christos int sz = ((iw0 >> LDST_sz_bits) & LDST_sz_mask); 2135 1.1 christos int aop = ((iw0 >> LDST_aop_bits) & LDST_aop_mask); 2136 1.1 christos int reg = ((iw0 >> LDST_reg_bits) & LDST_reg_mask); 2137 1.1 christos 2138 1.1 christos if (aop == 0 && sz == 0 && Z == 0 && W == 0) 2139 1.1 christos return DREG_MASK (reg); 2140 1.1 christos else if (aop == 0 && sz == 0 && Z == 1 && W == 0) 2141 1.1 christos return 0; 2142 1.1 christos else if (aop == 0 && sz == 1 && Z == 0 && W == 0) 2143 1.1 christos return DREG_MASK (reg); 2144 1.1 christos else if (aop == 0 && sz == 1 && Z == 1 && W == 0) 2145 1.1 christos return DREG_MASK (reg); 2146 1.1 christos else if (aop == 0 && sz == 2 && Z == 0 && W == 0) 2147 1.1 christos return DREG_MASK (reg); 2148 1.1 christos else if (aop == 0 && sz == 2 && Z == 1 && W == 0) 2149 1.1 christos return DREG_MASK (reg); 2150 1.1 christos else if (aop == 1 && sz == 0 && Z == 0 && W == 0) 2151 1.1 christos return DREG_MASK (reg); 2152 1.1 christos else if (aop == 1 && sz == 0 && Z == 1 && W == 0) 2153 1.1 christos return 0; 2154 1.1 christos else if (aop == 1 && sz == 1 && Z == 0 && W == 0) 2155 1.1 christos return DREG_MASK (reg); 2156 1.1 christos else if (aop == 1 && sz == 1 && Z == 1 && W == 0) 2157 1.1 christos return DREG_MASK (reg); 2158 1.1 christos else if (aop == 1 && sz == 2 && Z == 0 && W == 0) 2159 1.1 christos return DREG_MASK (reg); 2160 1.1 christos else if (aop == 1 && sz == 2 && Z == 1 && W == 0) 2161 1.1 christos return DREG_MASK (reg); 2162 1.1 christos else if (aop == 2 && sz == 0 && Z == 0 && W == 0) 2163 1.1 christos return DREG_MASK (reg); 2164 1.1 christos else if (aop == 2 && sz == 0 && Z == 1 && W == 0) 2165 1.1 christos return 0; 2166 1.1 christos else if (aop == 2 && sz == 1 && Z == 0 && W == 0) 2167 1.1 christos return DREG_MASK (reg); 2168 1.1 christos else if (aop == 2 && sz == 1 && Z == 1 && W == 0) 2169 1.1 christos return DREG_MASK (reg); 2170 1.1 christos else if (aop == 2 && sz == 2 && Z == 0 && W == 0) 2171 1.1 christos return DREG_MASK (reg); 2172 1.1 christos else if (aop == 2 && sz == 2 && Z == 1 && W == 0) 2173 1.1 christos return DREG_MASK (reg); 2174 1.1 christos else if (aop == 0 && sz == 0 && Z == 0 && W == 1) 2175 1.1 christos return 0; 2176 1.1 christos else if (aop == 0 && sz == 0 && Z == 1 && W == 1) 2177 1.1 christos return 0; 2178 1.1 christos else if (aop == 0 && sz == 1 && Z == 0 && W == 1) 2179 1.1 christos return 0; 2180 1.1 christos else if (aop == 0 && sz == 2 && Z == 0 && W == 1) 2181 1.1 christos return 0; 2182 1.1 christos else if (aop == 1 && sz == 0 && Z == 0 && W == 1) 2183 1.1 christos return 0; 2184 1.1 christos else if (aop == 1 && sz == 0 && Z == 1 && W == 1) 2185 1.1 christos return 0; 2186 1.1 christos else if (aop == 1 && sz == 1 && Z == 0 && W == 1) 2187 1.1 christos return 0; 2188 1.1 christos else if (aop == 1 && sz == 2 && Z == 0 && W == 1) 2189 1.1 christos return 0; 2190 1.1 christos else if (aop == 2 && sz == 0 && Z == 0 && W == 1) 2191 1.1 christos return 0; 2192 1.1 christos else if (aop == 2 && sz == 0 && Z == 1 && W == 1) 2193 1.1 christos return 0; 2194 1.1 christos else if (aop == 2 && sz == 1 && Z == 0 && W == 1) 2195 1.1 christos return 0; 2196 1.1 christos else if (aop == 2 && sz == 2 && Z == 0 && W == 1) 2197 1.1 christos return 0; 2198 1.1 christos 2199 1.1 christos abort (); 2200 1.1 christos } 2201 1.1 christos 2202 1.1 christos static int 2203 1.1 christos decode_LDSTiiFP_0 (int iw0) 2204 1.1 christos { 2205 1.1 christos /* LDSTiiFP 2206 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2207 1.1 christos | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........| 2208 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2209 1.1 christos int reg = ((iw0 >> LDSTiiFP_reg_bits) & LDSTiiFP_reg_mask); 2210 1.1 christos int W = ((iw0 >> LDSTiiFP_W_bits) & LDSTiiFP_W_mask); 2211 1.1 christos 2212 1.1 christos if (W == 0) 2213 1.1 christos return reg < 8 ? DREG_MASK (reg) : 0; 2214 1.1 christos else 2215 1.1 christos return 0; 2216 1.1 christos } 2217 1.1 christos 2218 1.1 christos static int 2219 1.1 christos decode_LDSTii_0 (int iw0) 2220 1.1 christos { 2221 1.1 christos /* LDSTii 2222 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2223 1.1 christos | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......| 2224 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2225 1.1 christos int reg = ((iw0 >> LDSTii_reg_bit) & LDSTii_reg_mask); 2226 1.1 christos int opc = ((iw0 >> LDSTii_op_bit) & LDSTii_op_mask); 2227 1.1 christos int W = ((iw0 >> LDSTii_W_bit) & LDSTii_W_mask); 2228 1.1 christos 2229 1.1 christos if (W == 0 && opc != 3) 2230 1.1 christos return DREG_MASK (reg); 2231 1.1 christos else if (W == 0 && opc == 3) 2232 1.1 christos return 0; 2233 1.1 christos else if (W == 1 && opc == 0) 2234 1.1 christos return 0; 2235 1.1 christos else if (W == 1 && opc == 1) 2236 1.1 christos return 0; 2237 1.1 christos else if (W == 1 && opc == 3) 2238 1.1 christos return 0; 2239 1.1 christos 2240 1.1 christos abort (); 2241 1.1 christos } 2242 1.1 christos 2243 1.1 christos static int 2244 1.1 christos decode_dsp32mac_0 (int iw0, int iw1) 2245 1.1 christos { 2246 1.1 christos int result = 0; 2247 1.1 christos /* dsp32mac 2248 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2249 1.1 christos | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...| 2250 1.1 christos |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..| 2251 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2252 1.1 christos int op1 = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask); 2253 1.1 christos int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask); 2254 1.1 christos int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask); 2255 1.1 christos int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask); 2256 1.1 christos int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask); 2257 1.1 christos int MM = ((iw1 >> DSP32Mac_MM_bits) & DSP32Mac_MM_mask); 2258 1.1 christos int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask); 2259 1.1 christos int op0 = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask); 2260 1.1 christos 2261 1.1 christos if (w0 == 0 && w1 == 0 && op1 == 3 && op0 == 3) 2262 1.1 christos return 0; 2263 1.1 christos 2264 1.1 christos if (op1 == 3 && MM) 2265 1.1 christos return 0; 2266 1.1 christos 2267 1.1 christos if ((w1 || w0) && mmod == M_W32) 2268 1.1 christos return 0; 2269 1.1 christos 2270 1.1 christos if (((1 << mmod) & (P ? 0x131b : 0x1b5f)) == 0) 2271 1.1 christos return 0; 2272 1.1 christos 2273 1.1 christos if (w1 == 1 || op1 != 3) 2274 1.1 christos { 2275 1.1 christos if (w1) 2276 1.1 christos { 2277 1.1 christos if (P) 2278 1.1 christos return DREG_MASK (dst + 1); 2279 1.1 christos else 2280 1.1 christos return DREGH_MASK (dst); 2281 1.1 christos } 2282 1.1 christos } 2283 1.1 christos 2284 1.1 christos if (w0 == 1 || op0 != 3) 2285 1.1 christos { 2286 1.1 christos if (w0) 2287 1.1 christos { 2288 1.1 christos if (P) 2289 1.1 christos return DREG_MASK (dst); 2290 1.1 christos else 2291 1.1 christos return DREGL_MASK (dst); 2292 1.1 christos } 2293 1.1 christos } 2294 1.1 christos 2295 1.1 christos return result; 2296 1.1 christos } 2297 1.1 christos 2298 1.1 christos static int 2299 1.1 christos decode_dsp32mult_0 (int iw0, int iw1) 2300 1.1 christos { 2301 1.1 christos /* dsp32mult 2302 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2303 1.1 christos | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...| 2304 1.1 christos |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..| 2305 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2306 1.1 christos int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask); 2307 1.1 christos int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask); 2308 1.1 christos int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask); 2309 1.1 christos int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask); 2310 1.1 christos int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask); 2311 1.1 christos int result = 0; 2312 1.1 christos 2313 1.1 christos if (w1 == 0 && w0 == 0) 2314 1.1 christos return 0; 2315 1.1 christos 2316 1.1 christos if (((1 << mmod) & (P ? 0x313 : 0x1b57)) == 0) 2317 1.1 christos return 0; 2318 1.1 christos 2319 1.1 christos if (w1) 2320 1.1 christos { 2321 1.1 christos if (P) 2322 1.1 christos return DREG_MASK (dst | 1); 2323 1.1 christos else 2324 1.1 christos return DREGH_MASK (dst); 2325 1.1 christos } 2326 1.1 christos 2327 1.1 christos if (w0) 2328 1.1 christos { 2329 1.1 christos if (P) 2330 1.1 christos return DREG_MASK (dst); 2331 1.1 christos else 2332 1.1 christos return DREGL_MASK (dst); 2333 1.1 christos } 2334 1.1 christos 2335 1.1 christos return result; 2336 1.1 christos } 2337 1.1 christos 2338 1.1 christos static int 2339 1.1 christos decode_dsp32alu_0 (int iw0, int iw1) 2340 1.1 christos { 2341 1.1 christos /* dsp32alu 2342 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2343 1.1 christos | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............| 2344 1.1 christos |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......| 2345 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2346 1.1 christos int s = ((iw1 >> DSP32Alu_s_bits) & DSP32Alu_s_mask); 2347 1.1 christos int x = ((iw1 >> DSP32Alu_x_bits) & DSP32Alu_x_mask); 2348 1.1 christos int aop = ((iw1 >> DSP32Alu_aop_bits) & DSP32Alu_aop_mask); 2349 1.1 christos int dst0 = ((iw1 >> DSP32Alu_dst0_bits) & DSP32Alu_dst0_mask); 2350 1.1 christos int dst1 = ((iw1 >> DSP32Alu_dst1_bits) & DSP32Alu_dst1_mask); 2351 1.1 christos int HL = ((iw0 >> (DSP32Alu_HL_bits - 16)) & DSP32Alu_HL_mask); 2352 1.1 christos int aopcde = ((iw0 >> (DSP32Alu_aopcde_bits - 16)) & DSP32Alu_aopcde_mask); 2353 1.1 christos 2354 1.1 christos if (aop == 0 && aopcde == 9 && s == 0) 2355 1.1 christos return 0; 2356 1.1 christos else if (aop == 2 && aopcde == 9 && HL == 0 && s == 0) 2357 1.1 christos return 0; 2358 1.1 christos else if (aop >= x * 2 && aopcde == 5) 2359 1.1 christos return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2360 1.1 christos else if (HL == 0 && aopcde == 2) 2361 1.1 christos return DREGL_MASK (dst0); 2362 1.1 christos else if (HL == 1 && aopcde == 2) 2363 1.1 christos return DREGH_MASK (dst0); 2364 1.1 christos else if (HL == 0 && aopcde == 3) 2365 1.1 christos return DREGL_MASK (dst0); 2366 1.1 christos else if (HL == 1 && aopcde == 3) 2367 1.1 christos return DREGH_MASK (dst0); 2368 1.1 christos 2369 1.1 christos else if (aop == 0 && aopcde == 9 && s == 1) 2370 1.1 christos return 0; 2371 1.1 christos else if (aop == 1 && aopcde == 9 && s == 0) 2372 1.1 christos return 0; 2373 1.1 christos else if (aop == 2 && aopcde == 9 && s == 1) 2374 1.1 christos return 0; 2375 1.1 christos else if (aop == 3 && aopcde == 9 && s == 0) 2376 1.1 christos return 0; 2377 1.1 christos else if (aopcde == 8) 2378 1.1 christos return 0; 2379 1.1 christos else if (aop == 0 && aopcde == 11) 2380 1.1 christos return DREG_MASK (dst0); 2381 1.1 christos else if (aop == 1 && aopcde == 11) 2382 1.1 christos return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2383 1.1 christos else if (aopcde == 11) 2384 1.1 christos return 0; 2385 1.1 christos else if (aopcde == 22) 2386 1.1 christos return DREG_MASK (dst0); 2387 1.1 christos 2388 1.1 christos else if ((aop == 0 || aop == 1) && aopcde == 14) 2389 1.1 christos return 0; 2390 1.1 christos else if (aop == 3 && HL == 0 && aopcde == 14) 2391 1.1 christos return 0; 2392 1.1 christos 2393 1.1 christos else if (aop == 3 && HL == 0 && aopcde == 15) 2394 1.1 christos return DREG_MASK (dst0); 2395 1.1 christos 2396 1.1 christos else if (aop == 1 && aopcde == 16) 2397 1.1 christos return 0; 2398 1.1 christos 2399 1.1 christos else if (aop == 0 && aopcde == 16) 2400 1.1 christos return 0; 2401 1.1 christos 2402 1.1 christos else if (aop == 3 && HL == 0 && aopcde == 16) 2403 1.1 christos return 0; 2404 1.1 christos 2405 1.1 christos else if (aop == 3 && HL == 0 && aopcde == 7) 2406 1.1 christos return DREG_MASK (dst0); 2407 1.1 christos else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 7) 2408 1.1 christos return DREG_MASK (dst0); 2409 1.1 christos 2410 1.1 christos else if (aop == 0 && aopcde == 12) 2411 1.1 christos return DREG_MASK (dst0); 2412 1.1 christos else if (aop == 1 && aopcde == 12) 2413 1.1 christos return DREG_MASK (dst0) | DREG_MASK (dst1); 2414 1.1 christos else if (aop == 3 && aopcde == 12) 2415 1.1 christos return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2416 1.1 christos 2417 1.1 christos else if (aopcde == 0) 2418 1.1 christos return DREG_MASK (dst0); 2419 1.1 christos else if (aopcde == 1) 2420 1.1 christos return DREG_MASK (dst0) | DREG_MASK (dst1); 2421 1.1 christos 2422 1.1 christos else if (aop == 0 && aopcde == 10) 2423 1.1 christos return DREGL_MASK (dst0); 2424 1.1 christos else if (aop == 1 && aopcde == 10) 2425 1.1 christos return DREGL_MASK (dst0); 2426 1.1 christos 2427 1.1 christos else if ((aop == 1 || aop == 0) && aopcde == 4) 2428 1.1 christos return DREG_MASK (dst0); 2429 1.1 christos else if (aop == 2 && aopcde == 4) 2430 1.1 christos return DREG_MASK (dst0) | DREG_MASK (dst1); 2431 1.1 christos 2432 1.1 christos else if (aop == 0 && aopcde == 17) 2433 1.1 christos return DREG_MASK (dst0) | DREG_MASK (dst1); 2434 1.1 christos else if (aop == 1 && aopcde == 17) 2435 1.1 christos return DREG_MASK (dst0) | DREG_MASK (dst1); 2436 1.1 christos else if (aop == 0 && aopcde == 18) 2437 1.1 christos return 0; 2438 1.1 christos else if (aop == 3 && aopcde == 18) 2439 1.1 christos return 0; 2440 1.1 christos 2441 1.1 christos else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 6) 2442 1.1 christos return DREG_MASK (dst0); 2443 1.1 christos 2444 1.1 christos else if ((aop == 0 || aop == 1) && aopcde == 20) 2445 1.1 christos return DREG_MASK (dst0); 2446 1.1 christos 2447 1.1 christos else if ((aop == 0 || aop == 1) && aopcde == 21) 2448 1.1 christos return DREG_MASK (dst0) | DREG_MASK (dst1); 2449 1.1 christos 2450 1.1 christos else if (aop == 0 && aopcde == 23 && HL == 1) 2451 1.1 christos return DREG_MASK (dst0); 2452 1.1 christos else if (aop == 0 && aopcde == 23 && HL == 0) 2453 1.1 christos return DREG_MASK (dst0); 2454 1.1 christos 2455 1.1 christos else if (aop == 0 && aopcde == 24) 2456 1.1 christos return DREG_MASK (dst0); 2457 1.1 christos else if (aop == 1 && aopcde == 24) 2458 1.1 christos return DREG_MASK (dst0) | DREG_MASK (dst1); 2459 1.1 christos else if (aopcde == 13) 2460 1.1 christos return DREG_MASK (dst0) | DREG_MASK (dst1); 2461 1.1 christos else 2462 1.1 christos return 0; 2463 1.1 christos 2464 1.1 christos return 4; 2465 1.1 christos } 2466 1.1 christos 2467 1.1 christos static int 2468 1.1 christos decode_dsp32shift_0 (int iw0, int iw1) 2469 1.1 christos { 2470 1.1 christos /* dsp32shift 2471 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2472 1.1 christos | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............| 2473 1.1 christos |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......| 2474 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2475 1.1 christos int HLs = ((iw1 >> DSP32Shift_HLs_bits) & DSP32Shift_HLs_mask); 2476 1.1 christos int sop = ((iw1 >> DSP32Shift_sop_bits) & DSP32Shift_sop_mask); 2477 1.1 christos int src0 = ((iw1 >> DSP32Shift_src0_bits) & DSP32Shift_src0_mask); 2478 1.1 christos int src1 = ((iw1 >> DSP32Shift_src1_bits) & DSP32Shift_src1_mask); 2479 1.1 christos int dst0 = ((iw1 >> DSP32Shift_dst0_bits) & DSP32Shift_dst0_mask); 2480 1.1 christos int sopcde = ((iw0 >> (DSP32Shift_sopcde_bits - 16)) & DSP32Shift_sopcde_mask); 2481 1.1 christos 2482 1.1 christos if (sop == 0 && sopcde == 0) 2483 1.1 christos return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2484 1.1 christos else if (sop == 1 && sopcde == 0) 2485 1.1 christos return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2486 1.1 christos else if (sop == 2 && sopcde == 0) 2487 1.1 christos return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2488 1.1 christos else if (sop == 0 && sopcde == 3) 2489 1.1 christos return 0; 2490 1.1 christos else if (sop == 1 && sopcde == 3) 2491 1.1 christos return 0; 2492 1.1 christos else if (sop == 2 && sopcde == 3) 2493 1.1 christos return 0; 2494 1.1 christos else if (sop == 3 && sopcde == 3) 2495 1.1 christos return DREG_MASK (dst0); 2496 1.1 christos else if (sop == 0 && sopcde == 1) 2497 1.1 christos return DREG_MASK (dst0); 2498 1.1 christos else if (sop == 1 && sopcde == 1) 2499 1.1 christos return DREG_MASK (dst0); 2500 1.1 christos else if (sop == 2 && sopcde == 1) 2501 1.1 christos return DREG_MASK (dst0); 2502 1.1 christos else if (sopcde == 2) 2503 1.1 christos return DREG_MASK (dst0); 2504 1.1 christos else if (sopcde == 4) 2505 1.1 christos return DREG_MASK (dst0); 2506 1.1 christos else if (sop == 0 && sopcde == 5) 2507 1.1 christos return DREGL_MASK (dst0); 2508 1.1 christos else if (sop == 1 && sopcde == 5) 2509 1.1 christos return DREGL_MASK (dst0); 2510 1.1 christos else if (sop == 2 && sopcde == 5) 2511 1.1 christos return DREGL_MASK (dst0); 2512 1.1 christos else if (sop == 0 && sopcde == 6) 2513 1.1 christos return DREGL_MASK (dst0); 2514 1.1 christos else if (sop == 1 && sopcde == 6) 2515 1.1 christos return DREGL_MASK (dst0); 2516 1.1 christos else if (sop == 3 && sopcde == 6) 2517 1.1 christos return DREGL_MASK (dst0); 2518 1.1 christos else if (sop == 0 && sopcde == 7) 2519 1.1 christos return DREGL_MASK (dst0); 2520 1.1 christos else if (sop == 1 && sopcde == 7) 2521 1.1 christos return DREGL_MASK (dst0); 2522 1.1 christos else if (sop == 2 && sopcde == 7) 2523 1.1 christos return DREGL_MASK (dst0); 2524 1.1 christos else if (sop == 3 && sopcde == 7) 2525 1.1 christos return DREGL_MASK (dst0); 2526 1.1 christos else if (sop == 0 && sopcde == 8) 2527 1.1 christos return DREG_MASK (src0) | DREG_MASK (src1); 2528 1.1 christos #if 0 2529 1.1 christos { 2530 1.1 christos OUTS (outf, "BITMUX ("); 2531 1.1 christos OUTS (outf, dregs (src0)); 2532 1.1 christos OUTS (outf, ", "); 2533 1.1 christos OUTS (outf, dregs (src1)); 2534 1.1 christos OUTS (outf, ", A0) (ASR)"); 2535 1.1 christos } 2536 1.1 christos #endif 2537 1.1 christos else if (sop == 1 && sopcde == 8) 2538 1.1 christos return DREG_MASK (src0) | DREG_MASK (src1); 2539 1.1 christos #if 0 2540 1.1 christos { 2541 1.1 christos OUTS (outf, "BITMUX ("); 2542 1.1 christos OUTS (outf, dregs (src0)); 2543 1.1 christos OUTS (outf, ", "); 2544 1.1 christos OUTS (outf, dregs (src1)); 2545 1.1 christos OUTS (outf, ", A0) (ASL)"); 2546 1.1 christos } 2547 1.1 christos #endif 2548 1.1 christos else if (sopcde == 9) 2549 1.1 christos return sop < 2 ? DREGL_MASK (dst0) : DREG_MASK (dst0); 2550 1.1 christos else if (sopcde == 10) 2551 1.1 christos return DREG_MASK (dst0); 2552 1.1 christos else if (sop == 0 && sopcde == 11) 2553 1.1 christos return DREGL_MASK (dst0); 2554 1.1 christos else if (sop == 1 && sopcde == 11) 2555 1.1 christos return DREGL_MASK (dst0); 2556 1.1 christos else if (sop == 0 && sopcde == 12) 2557 1.1 christos return 0; 2558 1.1 christos else if (sop == 1 && sopcde == 12) 2559 1.1 christos return DREGL_MASK (dst0); 2560 1.1 christos else if (sop == 0 && sopcde == 13) 2561 1.1 christos return DREG_MASK (dst0); 2562 1.1 christos else if (sop == 1 && sopcde == 13) 2563 1.1 christos return DREG_MASK (dst0); 2564 1.1 christos else if (sop == 2 && sopcde == 13) 2565 1.1 christos return DREG_MASK (dst0); 2566 1.1 christos 2567 1.1 christos abort (); 2568 1.1 christos } 2569 1.1 christos 2570 1.1 christos static int 2571 1.1 christos decode_dsp32shiftimm_0 (int iw0, int iw1) 2572 1.1 christos { 2573 1.1 christos /* dsp32shiftimm 2574 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ 2575 1.1 christos | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............| 2576 1.1 christos |.sop...|.HLs...|.dst0......|.immag.................|.src1......| 2577 1.1 christos +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */ 2578 1.1 christos int sop = ((iw1 >> DSP32ShiftImm_sop_bits) & DSP32ShiftImm_sop_mask); 2579 1.1 christos int bit8 = ((iw1 >> 8) & 0x1); 2580 1.1 christos int dst0 = ((iw1 >> DSP32ShiftImm_dst0_bits) & DSP32ShiftImm_dst0_mask); 2581 1.1 christos int sopcde = ((iw0 >> (DSP32ShiftImm_sopcde_bits - 16)) & DSP32ShiftImm_sopcde_mask); 2582 1.1 christos int HLs = ((iw1 >> DSP32ShiftImm_HLs_bits) & DSP32ShiftImm_HLs_mask); 2583 1.1 christos 2584 1.1 christos 2585 1.1 christos if (sop == 0 && sopcde == 0) 2586 1.1 christos return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2587 1.1 christos else if (sop == 1 && sopcde == 0 && bit8 == 0) 2588 1.1 christos return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2589 1.1 christos else if (sop == 1 && sopcde == 0 && bit8 == 1) 2590 1.1 christos return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2591 1.1 christos else if (sop == 2 && sopcde == 0 && bit8 == 0) 2592 1.1 christos return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2593 1.1 christos else if (sop == 2 && sopcde == 0 && bit8 == 1) 2594 1.1 christos return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0); 2595 1.1 christos else if (sop == 2 && sopcde == 3 && HLs == 1) 2596 1.1 christos return 0; 2597 1.1 christos else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 0) 2598 1.1 christos return 0; 2599 1.1 christos else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 1) 2600 1.1 christos return 0; 2601 1.1 christos else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 0) 2602 1.1 christos return 0; 2603 1.1 christos else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 1) 2604 1.1 christos return 0; 2605 1.1 christos else if (sop == 1 && sopcde == 3 && HLs == 0) 2606 1.1 christos return 0; 2607 1.1 christos else if (sop == 1 && sopcde == 3 && HLs == 1) 2608 1.1 christos return 0; 2609 1.1 christos else if (sop == 2 && sopcde == 3 && HLs == 0) 2610 1.1 christos return 0; 2611 1.1 christos else if (sop == 1 && sopcde == 1 && bit8 == 0) 2612 1.1 christos return DREG_MASK (dst0); 2613 1.1 christos else if (sop == 1 && sopcde == 1 && bit8 == 1) 2614 1.1 christos return DREG_MASK (dst0); 2615 1.1 christos else if (sop == 2 && sopcde == 1 && bit8 == 1) 2616 1.1 christos return DREG_MASK (dst0); 2617 1.1 christos else if (sop == 2 && sopcde == 1 && bit8 == 0) 2618 1.1 christos return DREG_MASK (dst0); 2619 1.1 christos else if (sop == 0 && sopcde == 1) 2620 1.1 christos return DREG_MASK (dst0); 2621 1.1 christos else if (sop == 1 && sopcde == 2) 2622 1.1 christos return DREG_MASK (dst0); 2623 1.1 christos else if (sop == 2 && sopcde == 2 && bit8 == 1) 2624 1.1 christos return DREG_MASK (dst0); 2625 1.1 christos else if (sop == 2 && sopcde == 2 && bit8 == 0) 2626 1.1 christos return DREG_MASK (dst0); 2627 1.1 christos else if (sop == 3 && sopcde == 2) 2628 1.1 christos return DREG_MASK (dst0); 2629 1.1 christos else if (sop == 0 && sopcde == 2) 2630 1.1 christos return DREG_MASK (dst0); 2631 1.1 christos 2632 1.1 christos abort (); 2633 1.1 christos } 2634 1.1 christos 2635 1.1 christos int 2636 1.1 christos insn_regmask (int iw0, int iw1) 2637 1.1 christos { 2638 1.1 christos if ((iw0 & 0xf7ff) == 0xc003 && iw1 == 0x1800) 2639 1.1 christos return 0; /* MNOP */ 2640 1.1 christos else if ((iw0 & 0xff00) == 0x0000) 2641 1.1 christos return decode_ProgCtrl_0 (iw0); 2642 1.1 christos else if ((iw0 & 0xffc0) == 0x0240) 2643 1.1 christos abort (); 2644 1.1 christos else if ((iw0 & 0xff80) == 0x0100) 2645 1.1 christos abort (); 2646 1.1 christos else if ((iw0 & 0xfe00) == 0x0400) 2647 1.1 christos abort (); 2648 1.1 christos else if ((iw0 & 0xfe00) == 0x0600) 2649 1.1 christos abort (); 2650 1.1 christos else if ((iw0 & 0xf800) == 0x0800) 2651 1.1 christos abort (); 2652 1.1 christos else if ((iw0 & 0xffe0) == 0x0200) 2653 1.1 christos abort (); 2654 1.1 christos else if ((iw0 & 0xff00) == 0x0300) 2655 1.1 christos abort (); 2656 1.1 christos else if ((iw0 & 0xf000) == 0x1000) 2657 1.1 christos abort (); 2658 1.1 christos else if ((iw0 & 0xf000) == 0x2000) 2659 1.1 christos abort (); 2660 1.1 christos else if ((iw0 & 0xf000) == 0x3000) 2661 1.1 christos abort (); 2662 1.1 christos else if ((iw0 & 0xfc00) == 0x4000) 2663 1.1 christos abort (); 2664 1.1 christos else if ((iw0 & 0xfe00) == 0x4400) 2665 1.1 christos abort (); 2666 1.1 christos else if ((iw0 & 0xf800) == 0x4800) 2667 1.1 christos abort (); 2668 1.1 christos else if ((iw0 & 0xf000) == 0x5000) 2669 1.1 christos abort (); 2670 1.1 christos else if ((iw0 & 0xf800) == 0x6000) 2671 1.1 christos abort (); 2672 1.1 christos else if ((iw0 & 0xf800) == 0x6800) 2673 1.1 christos abort (); 2674 1.1 christos else if ((iw0 & 0xf000) == 0x8000) 2675 1.1 christos return decode_LDSTpmod_0 (iw0); 2676 1.1 christos else if ((iw0 & 0xff60) == 0x9e60) 2677 1.1 christos return decode_dagMODim_0 (iw0); 2678 1.1 christos else if ((iw0 & 0xfff0) == 0x9f60) 2679 1.1 christos return decode_dagMODik_0 (iw0); 2680 1.1 christos else if ((iw0 & 0xfc00) == 0x9c00) 2681 1.1 christos return decode_dspLDST_0 (iw0); 2682 1.1 christos else if ((iw0 & 0xf000) == 0x9000) 2683 1.1 christos return decode_LDST_0 (iw0); 2684 1.1 christos else if ((iw0 & 0xfc00) == 0xb800) 2685 1.1 christos return decode_LDSTiiFP_0 (iw0); 2686 1.1 christos else if ((iw0 & 0xe000) == 0xA000) 2687 1.1 christos return decode_LDSTii_0 (iw0); 2688 1.1 christos else if ((iw0 & 0xff80) == 0xe080 && (iw1 & 0x0C00) == 0x0000) 2689 1.1 christos abort (); 2690 1.1 christos else if ((iw0 & 0xff00) == 0xe100 && (iw1 & 0x0000) == 0x0000) 2691 1.1 christos abort (); 2692 1.1 christos else if ((iw0 & 0xfe00) == 0xe200 && (iw1 & 0x0000) == 0x0000) 2693 1.1 christos abort (); 2694 1.1 christos else if ((iw0 & 0xfc00) == 0xe400 && (iw1 & 0x0000) == 0x0000) 2695 1.1 christos abort (); 2696 1.1 christos else if ((iw0 & 0xfffe) == 0xe800 && (iw1 & 0x0000) == 0x0000) 2697 1.1 christos abort (); 2698 1.1 christos else if ((iw0 & 0xf600) == 0xc000 && (iw1 & 0x0000) == 0x0000) 2699 1.1 christos return decode_dsp32mac_0 (iw0, iw1); 2700 1.1 christos else if ((iw0 & 0xf600) == 0xc200 && (iw1 & 0x0000) == 0x0000) 2701 1.1 christos return decode_dsp32mult_0 (iw0, iw1); 2702 1.1 christos else if ((iw0 & 0xf7c0) == 0xc400 && (iw1 & 0x0000) == 0x0000) 2703 1.1 christos return decode_dsp32alu_0 (iw0, iw1); 2704 1.1 christos else if ((iw0 & 0xf780) == 0xc600 && (iw1 & 0x01c0) == 0x0000) 2705 1.1 christos return decode_dsp32shift_0 (iw0, iw1); 2706 1.1 christos else if ((iw0 & 0xf780) == 0xc680 && (iw1 & 0x0000) == 0x0000) 2707 1.1 christos return decode_dsp32shiftimm_0 (iw0, iw1); 2708 1.1 christos else if ((iw0 & 0xff00) == 0xf800) 2709 1.1 christos abort (); 2710 1.1 christos else if ((iw0 & 0xFFC0) == 0xf000 && (iw1 & 0x0000) == 0x0000) 2711 1.1 christos abort (); 2712 1.1 christos 2713 abort (); 2714 } 2715