1/* Table of relaxations for Xtensa assembly. 2 Copyright (C) 2003-2022 Free Software Foundation, Inc. 3 4 This file is part of GAS, the GNU Assembler. 5 6 GAS is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 GAS is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GAS; see the file COPYING. If not, write to 18 the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, 19 MA 02110-1301, USA. */ 20 21/* This file contains the code for generating runtime data structures 22 for relaxation pattern matching from statically specified strings. 23 Each action contains an instruction pattern to match and 24 preconditions for the match as well as an expansion if the pattern 25 matches. The preconditions can specify that two operands are the 26 same or an operand is a specific constant or register. The expansion 27 uses the bound variables from the pattern to specify that specific 28 operands from the pattern should be used in the result. 29 30 The code determines whether the condition applies to a constant or 31 a register depending on the type of the operand. You may get 32 unexpected results if you don't match the rule against the operand 33 type correctly. 34 35 The patterns match a language like: 36 37 INSN_PATTERN ::= INSN_TEMPL ( '|' PRECOND )* ( '?' OPTIONPRED )* 38 INSN_TEMPL ::= OPCODE ' ' [ OPERAND (',' OPERAND)* ] 39 OPCODE ::= id 40 OPERAND ::= CONSTANT | VARIABLE | SPECIALFN '(' VARIABLE ')' 41 SPECIALFN ::= 'HI24S' | 'F32MINUS' | 'LOW8' 42 | 'HI16' | 'LOW16' 43 VARIABLE ::= '%' id 44 PRECOND ::= OPERAND CMPOP OPERAND 45 CMPOP ::= '==' | '!=' 46 OPTIONPRED ::= OPTIONNAME ('+' OPTIONNAME) 47 OPTIONNAME ::= '"' id '"' 48 49 The replacement language 50 INSN_REPL ::= INSN_LABEL_LIT ( ';' INSN_LABEL_LIT )* 51 INSN_LABEL_LIT ::= INSN_TEMPL 52 | 'LABEL' 53 | 'LITERAL' VARIABLE 54 55 The operands in a PRECOND must be constants or variables bound by 56 the INSN_PATTERN. 57 58 The configuration options define a predicate on the availability of 59 options which must be TRUE for this rule to be valid. Examples are 60 requiring "density" for replacements with density instructions, 61 requiring "const16" for replacements that require const16 62 instructions, etc. The names are interpreted by the assembler to a 63 truth value for a particular frag. 64 65 The operands in the INSN_REPL must be constants, variables bound in 66 the associated INSN_PATTERN, special variables that are bound in 67 the INSN_REPL by LABEL or LITERAL definitions, or special value 68 manipulation functions. 69 70 A simple example of a replacement pattern: 71 {"movi.n %as,%imm", "movi %as,%imm"} would convert the narrow 72 movi.n instruction to the wide movi instruction. 73 74 A more complex example of a branch around: 75 {"beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"} 76 would convert a branch to a negated branch to the following instruction 77 with a jump to the original label. 78 79 An Xtensa-specific example that generates a literal: 80 {"movi %at,%imm", "LITERAL %imm; l32r %at,%LITERAL"} 81 will convert a movi instruction to an l32r of a literal 82 literal defined in the literal pool. 83 84 Even more complex is a conversion of a load with immediate offset 85 to a load of a freshly generated literal, an explicit add and 86 a load with 0 offset. This transformation is only valid, though 87 when the first and second operands are not the same as specified 88 by the "| %at!=%as" precondition clause. 89 {"l32i %at,%as,%imm | %at!=%as", 90 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"} */ 91 92#include "as.h" 93#include "xtensa-isa.h" 94#include "xtensa-relax.h" 95#include <stddef.h> 96#include "xtensa-config.h" 97 98#ifndef XCHAL_HAVE_WIDE_BRANCHES 99#define XCHAL_HAVE_WIDE_BRANCHES 0 100#endif 101 102/* Imported from bfd. */ 103extern xtensa_isa xtensa_default_isa; 104 105/* The opname_list is a small list of names that we use for opcode and 106 operand variable names to simplify ownership of these commonly used 107 strings. Strings entered in the table can be compared by pointer 108 equality. */ 109 110typedef struct opname_list_struct opname_list; 111typedef opname_list opname_e; 112 113struct opname_list_struct 114{ 115 char *opname; 116 opname_list *next; 117}; 118 119static opname_list *local_opnames = NULL; 120 121 122/* The "opname_map" and its element structure "opname_map_e" are used 123 for binding an operand number to a name or a constant. */ 124 125typedef struct opname_map_e_struct opname_map_e; 126typedef struct opname_map_struct opname_map; 127 128struct opname_map_e_struct 129{ 130 const char *operand_name; /* If null, then use constant_value. */ 131 int operand_num; 132 unsigned constant_value; 133 opname_map_e *next; 134}; 135 136struct opname_map_struct 137{ 138 opname_map_e *head; 139 opname_map_e **tail; 140}; 141 142/* The "precond_list" and its element structure "precond_e" represents 143 explicit preconditions comparing operand variables and constants. 144 In the "precond_e" structure, a variable is identified by the name 145 in the "opname" field. If that field is NULL, then the operand 146 is the constant in field "opval". */ 147 148typedef struct precond_e_struct precond_e; 149typedef struct precond_list_struct precond_list; 150 151struct precond_e_struct 152{ 153 const char *opname1; 154 unsigned opval1; 155 CmpOp cmpop; 156 const char *opname2; 157 unsigned opval2; 158 precond_e *next; 159}; 160 161struct precond_list_struct 162{ 163 precond_e *head; 164 precond_e **tail; 165}; 166 167 168/* The insn_templ represents the INSN_TEMPL instruction template. It 169 is an opcode name with a list of operands. These are used for 170 instruction patterns and replacement patterns. */ 171 172typedef struct insn_templ_struct insn_templ; 173struct insn_templ_struct 174{ 175 const char *opcode_name; 176 opname_map operand_map; 177}; 178 179 180/* The insn_pattern represents an INSN_PATTERN instruction pattern. 181 It is an instruction template with preconditions that specify when 182 it actually matches a given instruction. */ 183 184typedef struct insn_pattern_struct insn_pattern; 185struct insn_pattern_struct 186{ 187 insn_templ t; 188 precond_list preconds; 189 ReqOptionList *options; 190}; 191 192 193/* The "insn_repl" and associated element structure "insn_repl_e" 194 instruction replacement list is a list of 195 instructions/LITERALS/LABELS with constant operands or operands 196 with names bound to the operand names in the associated pattern. */ 197 198typedef struct insn_repl_e_struct insn_repl_e; 199struct insn_repl_e_struct 200{ 201 insn_templ t; 202 insn_repl_e *next; 203}; 204 205typedef struct insn_repl_struct insn_repl; 206struct insn_repl_struct 207{ 208 insn_repl_e *head; 209 insn_repl_e **tail; 210}; 211 212 213/* The split_rec is a vector of allocated char * pointers. */ 214 215typedef struct split_rec_struct split_rec; 216struct split_rec_struct 217{ 218 char **vec; 219 int count; 220}; 221 222/* The "string_pattern_pair" is a set of pairs containing instruction 223 patterns and replacement strings. */ 224 225typedef struct string_pattern_pair_struct string_pattern_pair; 226struct string_pattern_pair_struct 227{ 228 const char *pattern; 229 const char *replacement; 230}; 231 232 233/* The widen_spec_list is a list of valid substitutions that generate 234 wider representations. These are generally used to specify 235 replacements for instructions whose immediates do not fit their 236 encodings. A valid transition may require multiple steps of 237 one-to-one instruction replacements with a final multiple 238 instruction replacement. As an example, here are the transitions 239 required to replace an 'addi.n' with an 'addi', 'addmi'. 240 241 addi.n a4, 0x1010 242 => addi a4, 0x1010 243 => addmi a4, 0x1010 244 => addmi a4, 0x1000, addi a4, 0x10. 245 246 See the comments in xg_assembly_relax for some important details 247 regarding how these chains must be built. */ 248 249static string_pattern_pair widen_spec_list[] = 250{ 251 {"add.n %ar,%as,%at ? IsaUseDensityInstruction", "add %ar,%as,%at"}, 252 {"addi.n %ar,%as,%imm ? IsaUseDensityInstruction", "addi %ar,%as,%imm"}, 253 {"beqz.n %as,%label ? IsaUseDensityInstruction", "beqz %as,%label"}, 254 {"bnez.n %as,%label ? IsaUseDensityInstruction", "bnez %as,%label"}, 255 {"l32i.n %at,%as,%imm ? IsaUseDensityInstruction", "l32i %at,%as,%imm"}, 256 {"mov.n %at,%as ? IsaUseDensityInstruction", "or %at,%as,%as"}, 257 {"movi.n %as,%imm ? IsaUseDensityInstruction", "movi %as,%imm"}, 258 {"nop.n ? IsaUseDensityInstruction ? realnop", "nop"}, 259 {"nop.n ? IsaUseDensityInstruction ? no-realnop", "or 1,1,1"}, 260 {"ret.n %as ? IsaUseDensityInstruction", "ret %as"}, 261 {"retw.n %as ? IsaUseDensityInstruction", "retw %as"}, 262 {"s32i.n %at,%as,%imm ? IsaUseDensityInstruction", "s32i %at,%as,%imm"}, 263 {"srli %at,%as,%imm", "extui %at,%as,%imm,F32MINUS(%imm)"}, 264 {"slli %ar,%as,0", "or %ar,%as,%as"}, 265 266 /* Widening with literals or const16. */ 267 {"movi %at,%imm ? IsaUseL32R ", 268 "LITERAL %imm; l32r %at,%LITERAL"}, 269 {"movi %at,%imm ? IsaUseConst16", 270 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm)"}, 271 272 {"addi %ar,%as,%imm", "addmi %ar,%as,%imm"}, 273 /* LOW8 is the low 8 bits of the Immed 274 MID8S is the middle 8 bits of the Immed */ 275 {"addmi %ar,%as,%imm", "addmi %ar,%as,HI24S(%imm); addi %ar,%ar,LOW8(%imm)"}, 276 277 /* In the end convert to either an l32r or const16. */ 278 {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseL32R", 279 "LITERAL %imm; l32r %ar,%LITERAL; add %ar,%as,%ar"}, 280 {"addmi %ar,%as,%imm | %ar!=%as ? IsaUseConst16", 281 "const16 %ar,HI16U(%imm); const16 %ar,LOW16U(%imm); add %ar,%as,%ar"}, 282 283 /* Widening the load instructions with too-large immediates */ 284 {"l8ui %at,%as,%imm | %at!=%as ? IsaUseL32R", 285 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l8ui %at,%at,0"}, 286 {"l16si %at,%as,%imm | %at!=%as ? IsaUseL32R", 287 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l16si %at,%at,0"}, 288 {"l16ui %at,%as,%imm | %at!=%as ? IsaUseL32R", 289 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l16ui %at,%at,0"}, 290 {"l32i %at,%as,%imm | %at!=%as ? IsaUseL32R", 291 "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"}, 292 293 /* Widening load instructions with const16s. */ 294 {"l8ui %at,%as,%imm | %at!=%as ? IsaUseConst16", 295 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l8ui %at,%at,0"}, 296 {"l16si %at,%as,%imm | %at!=%as ? IsaUseConst16", 297 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16si %at,%at,0"}, 298 {"l16ui %at,%as,%imm | %at!=%as ? IsaUseConst16", 299 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l16ui %at,%at,0"}, 300 {"l32i %at,%as,%imm | %at!=%as ? IsaUseConst16", 301 "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l32i %at,%at,0"}, 302 303 /* Widening loops with literals. */ 304 {"loop %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R", 305 "loop %as,%LABEL;" 306 "rsr.lend %as;" /* LEND */ 307 "wsr.lbeg %as;" /* LBEG */ 308 "LITERAL %label;" 309 "l32r %as, %LITERAL;" 310 "nop;" 311 "wsr.lend %as;" 312 "isync;" 313 "rsr.lcount %as;" /* LCOUNT */ 314 "addi %as, %as, 1;" 315 "LABEL"}, 316 {"loopgtz %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R", 317 "beqz %as,%label;" 318 "bltz %as,%label;" 319 "loopgtz %as,%LABEL;" 320 "rsr.lend %as;" /* LEND */ 321 "wsr.lbeg %as;" /* LBEG */ 322 "LITERAL %label;" 323 "l32r %as, %LITERAL;" 324 "nop;" 325 "wsr.lend %as;" 326 "isync;" 327 "rsr.lcount %as;" /* LCOUNT */ 328 "addi %as, %as, 1;" 329 "LABEL"}, 330 {"loopnez %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R", 331 "beqz %as,%label;" 332 "loopnez %as,%LABEL;" 333 "rsr.lend %as;" /* LEND */ 334 "wsr.lbeg %as;" /* LBEG */ 335 "LITERAL %label;" 336 "l32r %as, %LITERAL;" 337 "nop;" 338 "wsr.lend %as;" 339 "isync;" 340 "rsr.lcount %as;" /* LCOUNT */ 341 "addi %as, %as, 1;" 342 "LABEL"}, 343 344 /* Widening loops with const16. */ 345 {"loop %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16", 346 "loop %as,%LABEL;" 347 "rsr.lend %as;" /* LEND */ 348 "wsr.lbeg %as;" /* LBEG */ 349 "const16 %as,HI16U(%label);" 350 "const16 %as,LOW16U(%label);" 351 "wsr.lend %as;" 352 "isync;" 353 "rsr.lcount %as;" /* LCOUNT */ 354 "addi %as, %as, 1;" 355 "LABEL"}, 356 {"loopgtz %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16", 357 "beqz %as,%label;" 358 "bltz %as,%label;" 359 "loopgtz %as,%LABEL;" 360 "rsr.lend %as;" /* LEND */ 361 "wsr.lbeg %as;" /* LBEG */ 362 "const16 %as,HI16U(%label);" 363 "const16 %as,LOW16U(%label);" 364 "wsr.lend %as;" 365 "isync;" 366 "rsr.lcount %as;" /* LCOUNT */ 367 "addi %as, %as, 1;" 368 "LABEL"}, 369 {"loopnez %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16", 370 "beqz %as,%label;" 371 "loopnez %as,%LABEL;" 372 "rsr.lend %as;" /* LEND */ 373 "wsr.lbeg %as;" /* LBEG */ 374 "const16 %as,HI16U(%label);" 375 "const16 %as,LOW16U(%label);" 376 "wsr.lend %as;" 377 "isync;" 378 "rsr.lcount %as;" /* LCOUNT */ 379 "addi %as, %as, 1;" 380 "LABEL"}, 381 382 /* Relaxing to wide branches. Order is important here. With wide 383 branches, there is more than one correct relaxation for an 384 out-of-range branch. Put the wide branch relaxations first in the 385 table since they are more efficient than the branch-around 386 relaxations. */ 387 388 {"beqz %as,%label ? IsaUseWideBranches", "WIDE.beqz %as,%label"}, 389 {"bnez %as,%label ? IsaUseWideBranches", "WIDE.bnez %as,%label"}, 390 {"bgez %as,%label ? IsaUseWideBranches", "WIDE.bgez %as,%label"}, 391 {"bltz %as,%label ? IsaUseWideBranches", "WIDE.bltz %as,%label"}, 392 {"beqi %as,%imm,%label ? IsaUseWideBranches", "WIDE.beqi %as,%imm,%label"}, 393 {"bnei %as,%imm,%label ? IsaUseWideBranches", "WIDE.bnei %as,%imm,%label"}, 394 {"bgei %as,%imm,%label ? IsaUseWideBranches", "WIDE.bgei %as,%imm,%label"}, 395 {"blti %as,%imm,%label ? IsaUseWideBranches", "WIDE.blti %as,%imm,%label"}, 396 {"bgeui %as,%imm,%label ? IsaUseWideBranches", "WIDE.bgeui %as,%imm,%label"}, 397 {"bltui %as,%imm,%label ? IsaUseWideBranches", "WIDE.bltui %as,%imm,%label"}, 398 {"bbci %as,%imm,%label ? IsaUseWideBranches", "WIDE.bbci %as,%imm,%label"}, 399 {"bbsi %as,%imm,%label ? IsaUseWideBranches", "WIDE.bbsi %as,%imm,%label"}, 400 {"beq %as,%at,%label ? IsaUseWideBranches", "WIDE.beq %as,%at,%label"}, 401 {"bne %as,%at,%label ? IsaUseWideBranches", "WIDE.bne %as,%at,%label"}, 402 {"bge %as,%at,%label ? IsaUseWideBranches", "WIDE.bge %as,%at,%label"}, 403 {"blt %as,%at,%label ? IsaUseWideBranches", "WIDE.blt %as,%at,%label"}, 404 {"bgeu %as,%at,%label ? IsaUseWideBranches", "WIDE.bgeu %as,%at,%label"}, 405 {"bltu %as,%at,%label ? IsaUseWideBranches", "WIDE.bltu %as,%at,%label"}, 406 {"bany %as,%at,%label ? IsaUseWideBranches", "WIDE.bany %as,%at,%label"}, 407 {"bnone %as,%at,%label ? IsaUseWideBranches", "WIDE.bnone %as,%at,%label"}, 408 {"ball %as,%at,%label ? IsaUseWideBranches", "WIDE.ball %as,%at,%label"}, 409 {"bnall %as,%at,%label ? IsaUseWideBranches", "WIDE.bnall %as,%at,%label"}, 410 {"bbc %as,%at,%label ? IsaUseWideBranches", "WIDE.bbc %as,%at,%label"}, 411 {"bbs %as,%at,%label ? IsaUseWideBranches", "WIDE.bbs %as,%at,%label"}, 412 413 /* Widening branch comparisons eq/ne to zero. Prefer relaxing to narrow 414 branches if the density option is available. */ 415 {"beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL;j %label;LABEL"}, 416 {"bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL;j %label;LABEL"}, 417 {"beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"}, 418 {"bnez %as,%label", "beqz %as,%LABEL;j %label;LABEL"}, 419 {"WIDE.beqz %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%LABEL;j %label;LABEL"}, 420 {"WIDE.bnez %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%LABEL;j %label;LABEL"}, 421 {"WIDE.beqz %as,%label", "bnez %as,%LABEL;j %label;LABEL"}, 422 {"WIDE.bnez %as,%label", "beqz %as,%LABEL;j %label;LABEL"}, 423 424 /* Widening expect-taken branches. */ 425 {"beqzt %as,%label ? IsaUsePredictedBranches", "bnez %as,%LABEL;j %label;LABEL"}, 426 {"bnezt %as,%label ? IsaUsePredictedBranches", "beqz %as,%LABEL;j %label;LABEL"}, 427 {"beqt %as,%at,%label ? IsaUsePredictedBranches", "bne %as,%at,%LABEL;j %label;LABEL"}, 428 {"bnet %as,%at,%label ? IsaUsePredictedBranches", "beq %as,%at,%LABEL;j %label;LABEL"}, 429 430 /* Widening branches from the Xtensa boolean option. */ 431 {"bt %bs,%label ? IsaUseBooleans", "bf %bs,%LABEL;j %label;LABEL"}, 432 {"bf %bs,%label ? IsaUseBooleans", "bt %bs,%LABEL;j %label;LABEL"}, 433 434 /* Other branch-around-jump widenings. */ 435 {"bgez %as,%label", "bltz %as,%LABEL;j %label;LABEL"}, 436 {"bltz %as,%label", "bgez %as,%LABEL;j %label;LABEL"}, 437 {"beqi %as,%imm,%label", "bnei %as,%imm,%LABEL;j %label;LABEL"}, 438 {"bnei %as,%imm,%label", "beqi %as,%imm,%LABEL;j %label;LABEL"}, 439 {"bgei %as,%imm,%label", "blti %as,%imm,%LABEL;j %label;LABEL"}, 440 {"blti %as,%imm,%label", "bgei %as,%imm,%LABEL;j %label;LABEL"}, 441 {"bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL;j %label;LABEL"}, 442 {"bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL;j %label;LABEL"}, 443 {"bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL;j %label;LABEL"}, 444 {"bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL;j %label;LABEL"}, 445 {"beq %as,%at,%label", "bne %as,%at,%LABEL;j %label;LABEL"}, 446 {"bne %as,%at,%label", "beq %as,%at,%LABEL;j %label;LABEL"}, 447 {"bge %as,%at,%label", "blt %as,%at,%LABEL;j %label;LABEL"}, 448 {"blt %as,%at,%label", "bge %as,%at,%LABEL;j %label;LABEL"}, 449 {"bgeu %as,%at,%label", "bltu %as,%at,%LABEL;j %label;LABEL"}, 450 {"bltu %as,%at,%label", "bgeu %as,%at,%LABEL;j %label;LABEL"}, 451 {"bany %as,%at,%label", "bnone %as,%at,%LABEL;j %label;LABEL"}, 452 {"bnone %as,%at,%label", "bany %as,%at,%LABEL;j %label;LABEL"}, 453 {"ball %as,%at,%label", "bnall %as,%at,%LABEL;j %label;LABEL"}, 454 {"bnall %as,%at,%label", "ball %as,%at,%LABEL;j %label;LABEL"}, 455 {"bbc %as,%at,%label", "bbs %as,%at,%LABEL;j %label;LABEL"}, 456 {"bbs %as,%at,%label", "bbc %as,%at,%LABEL;j %label;LABEL"}, 457 458 {"WIDE.bgez %as,%label", "bltz %as,%LABEL;j %label;LABEL"}, 459 {"WIDE.bltz %as,%label", "bgez %as,%LABEL;j %label;LABEL"}, 460 {"WIDE.beqi %as,%imm,%label", "bnei %as,%imm,%LABEL;j %label;LABEL"}, 461 {"WIDE.bnei %as,%imm,%label", "beqi %as,%imm,%LABEL;j %label;LABEL"}, 462 {"WIDE.bgei %as,%imm,%label", "blti %as,%imm,%LABEL;j %label;LABEL"}, 463 {"WIDE.blti %as,%imm,%label", "bgei %as,%imm,%LABEL;j %label;LABEL"}, 464 {"WIDE.bgeui %as,%imm,%label", "bltui %as,%imm,%LABEL;j %label;LABEL"}, 465 {"WIDE.bltui %as,%imm,%label", "bgeui %as,%imm,%LABEL;j %label;LABEL"}, 466 {"WIDE.bbci %as,%imm,%label", "bbsi %as,%imm,%LABEL;j %label;LABEL"}, 467 {"WIDE.bbsi %as,%imm,%label", "bbci %as,%imm,%LABEL;j %label;LABEL"}, 468 {"WIDE.beq %as,%at,%label", "bne %as,%at,%LABEL;j %label;LABEL"}, 469 {"WIDE.bne %as,%at,%label", "beq %as,%at,%LABEL;j %label;LABEL"}, 470 {"WIDE.bge %as,%at,%label", "blt %as,%at,%LABEL;j %label;LABEL"}, 471 {"WIDE.blt %as,%at,%label", "bge %as,%at,%LABEL;j %label;LABEL"}, 472 {"WIDE.bgeu %as,%at,%label", "bltu %as,%at,%LABEL;j %label;LABEL"}, 473 {"WIDE.bltu %as,%at,%label", "bgeu %as,%at,%LABEL;j %label;LABEL"}, 474 {"WIDE.bany %as,%at,%label", "bnone %as,%at,%LABEL;j %label;LABEL"}, 475 {"WIDE.bnone %as,%at,%label", "bany %as,%at,%LABEL;j %label;LABEL"}, 476 {"WIDE.ball %as,%at,%label", "bnall %as,%at,%LABEL;j %label;LABEL"}, 477 {"WIDE.bnall %as,%at,%label", "ball %as,%at,%LABEL;j %label;LABEL"}, 478 {"WIDE.bbc %as,%at,%label", "bbs %as,%at,%LABEL;j %label;LABEL"}, 479 {"WIDE.bbs %as,%at,%label", "bbc %as,%at,%LABEL;j %label;LABEL"}, 480 481 /* Expanding calls with literals. */ 482 {"call0 %label,%ar0 ? IsaUseL32R", 483 "LITERAL %label; l32r a0,%LITERAL; callx0 a0,%ar0"}, 484 {"call4 %label,%ar4 ? IsaUseL32R", 485 "LITERAL %label; l32r a4,%LITERAL; callx4 a4,%ar4"}, 486 {"call8 %label,%ar8 ? IsaUseL32R", 487 "LITERAL %label; l32r a8,%LITERAL; callx8 a8,%ar8"}, 488 {"call12 %label,%ar12 ? IsaUseL32R", 489 "LITERAL %label; l32r a12,%LITERAL; callx12 a12,%ar12"}, 490 491 /* Expanding calls with const16. */ 492 {"call0 %label,%ar0 ? IsaUseConst16", 493 "const16 a0,HI16U(%label); const16 a0,LOW16U(%label); callx0 a0,%ar0"}, 494 {"call4 %label,%ar4 ? IsaUseConst16", 495 "const16 a4,HI16U(%label); const16 a4,LOW16U(%label); callx4 a4,%ar4"}, 496 {"call8 %label,%ar8 ? IsaUseConst16", 497 "const16 a8,HI16U(%label); const16 a8,LOW16U(%label); callx8 a8,%ar8"}, 498 {"call12 %label,%ar12 ? IsaUseConst16", 499 "const16 a12,HI16U(%label); const16 a12,LOW16U(%label); callx12 a12,%ar12"}, 500 501 /* Expanding j.l with literals. */ 502 {"j %label ? FREEREG ? IsaUseL32R", 503 "LITERAL %label; l32r FREEREG,%LITERAL; jx FREEREG"}, 504 /* Expanding j.l with const16. */ 505 {"j %label ? FREEREG ? IsaUseConst16", 506 "const16 FREEREG,HI16U(%label); const16 FREEREG,LOW16U(%label); jx FREEREG"}, 507}; 508 509#define WIDEN_COUNT (sizeof (widen_spec_list) / sizeof (string_pattern_pair)) 510 511 512/* The simplify_spec_list specifies simplifying transformations that 513 will reduce the instruction width or otherwise simplify an 514 instruction. These are usually applied before relaxation in the 515 assembler. It is always legal to simplify. Even for "addi as, 0", 516 the "addi.n as, 0" will eventually be widened back to an "addi 0" 517 after the widening table is applied. Note: The usage of this table 518 has changed somewhat so that it is entirely specific to "narrowing" 519 instructions to use the density option. This table is not used at 520 all when the density option is not available. */ 521 522string_pattern_pair simplify_spec_list[] = 523{ 524 {"add %ar,%as,%at ? IsaUseDensityInstruction", "add.n %ar,%as,%at"}, 525 {"addi.n %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"}, 526 {"addi %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"}, 527 {"addi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"}, 528 {"addmi %ar,%as,%imm ? IsaUseDensityInstruction", "addi.n %ar,%as,%imm"}, 529 {"beqz %as,%label ? IsaUseDensityInstruction", "beqz.n %as,%label"}, 530 {"bnez %as,%label ? IsaUseDensityInstruction", "bnez.n %as,%label"}, 531 {"l32i %at,%as,%imm ? IsaUseDensityInstruction", "l32i.n %at,%as,%imm"}, 532 {"movi %as,%imm ? IsaUseDensityInstruction", "movi.n %as,%imm"}, 533 {"nop ? realnop ? IsaUseDensityInstruction", "nop.n"}, 534 {"or %ar,%as,%at | %ar==%as | %as==%at ? IsaUseDensityInstruction", "nop.n"}, 535 {"or %ar,%as,%at | %ar!=%as | %as==%at ? IsaUseDensityInstruction", "mov.n %ar,%as"}, 536 {"ret %as ? IsaUseDensityInstruction", "ret.n %as"}, 537 {"retw %as ? IsaUseDensityInstruction", "retw.n %as"}, 538 {"s32i %at,%as,%imm ? IsaUseDensityInstruction", "s32i.n %at,%as,%imm"}, 539 {"slli %ar,%as,0 ? IsaUseDensityInstruction", "mov.n %ar,%as"} 540}; 541 542#define SIMPLIFY_COUNT \ 543 (sizeof (simplify_spec_list) / sizeof (string_pattern_pair)) 544 545 546/* Externally visible functions. */ 547 548extern bool xg_has_userdef_op_fn (OpType); 549extern long xg_apply_userdef_op_fn (OpType, long); 550 551 552static void 553append_transition (TransitionTable *tt, 554 xtensa_opcode opcode, 555 TransitionRule *t, 556 transition_cmp_fn cmp) 557{ 558 TransitionList *tl = XNEW (TransitionList); 559 TransitionList *prev; 560 TransitionList **t_p; 561 gas_assert (tt != NULL); 562 gas_assert (opcode < tt->num_opcodes); 563 564 prev = tt->table[opcode]; 565 tl->rule = t; 566 tl->next = NULL; 567 if (prev == NULL) 568 { 569 tt->table[opcode] = tl; 570 return; 571 } 572 573 for (t_p = &tt->table[opcode]; (*t_p) != NULL; t_p = &(*t_p)->next) 574 { 575 if (cmp && cmp (t, (*t_p)->rule) < 0) 576 { 577 /* Insert it here. */ 578 tl->next = *t_p; 579 *t_p = tl; 580 return; 581 } 582 } 583 (*t_p) = tl; 584} 585 586 587static void 588append_condition (TransitionRule *tr, Precondition *cond) 589{ 590 PreconditionList *pl = XNEW (PreconditionList); 591 PreconditionList *prev = tr->conditions; 592 PreconditionList *nxt; 593 594 pl->precond = cond; 595 pl->next = NULL; 596 if (prev == NULL) 597 { 598 tr->conditions = pl; 599 return; 600 } 601 nxt = prev->next; 602 while (nxt != NULL) 603 { 604 prev = nxt; 605 nxt = nxt->next; 606 } 607 prev->next = pl; 608} 609 610 611static void 612append_value_condition (TransitionRule *tr, 613 CmpOp cmp, 614 unsigned op1, 615 unsigned op2) 616{ 617 Precondition *cond = XNEW (Precondition); 618 619 cond->cmp = cmp; 620 cond->op_num = op1; 621 cond->typ = OP_OPERAND; 622 cond->op_data = op2; 623 append_condition (tr, cond); 624} 625 626 627static void 628append_constant_value_condition (TransitionRule *tr, 629 CmpOp cmp, 630 unsigned op1, 631 unsigned cnst) 632{ 633 Precondition *cond = XNEW (Precondition); 634 635 cond->cmp = cmp; 636 cond->op_num = op1; 637 cond->typ = OP_CONSTANT; 638 cond->op_data = cnst; 639 append_condition (tr, cond); 640} 641 642 643static void 644append_build_insn (TransitionRule *tr, BuildInstr *bi) 645{ 646 BuildInstr *prev = tr->to_instr; 647 BuildInstr *nxt; 648 649 bi->next = NULL; 650 if (prev == NULL) 651 { 652 tr->to_instr = bi; 653 return; 654 } 655 nxt = prev->next; 656 while (nxt != 0) 657 { 658 prev = nxt; 659 nxt = prev->next; 660 } 661 prev->next = bi; 662} 663 664 665static void 666append_op (BuildInstr *bi, BuildOp *b_op) 667{ 668 BuildOp *prev = bi->ops; 669 BuildOp *nxt; 670 671 if (prev == NULL) 672 { 673 bi->ops = b_op; 674 return; 675 } 676 nxt = prev->next; 677 while (nxt != NULL) 678 { 679 prev = nxt; 680 nxt = nxt->next; 681 } 682 prev->next = b_op; 683} 684 685 686static void 687append_literal_op (BuildInstr *bi, unsigned op1, unsigned src_op) 688{ 689 BuildOp *b_op = XNEW (BuildOp); 690 691 b_op->op_num = op1; 692 b_op->typ = OP_LITERAL; 693 b_op->op_data = src_op; 694 b_op->next = NULL; 695 append_op (bi, b_op); 696} 697 698 699static void 700append_label_op (BuildInstr *bi, unsigned op1) 701{ 702 BuildOp *b_op = XNEW (BuildOp); 703 704 b_op->op_num = op1; 705 b_op->typ = OP_LABEL; 706 b_op->op_data = 0; 707 b_op->next = NULL; 708 append_op (bi, b_op); 709} 710 711 712static void 713append_constant_op (BuildInstr *bi, unsigned op1, unsigned cnst) 714{ 715 BuildOp *b_op = XNEW (BuildOp); 716 717 b_op->op_num = op1; 718 b_op->typ = OP_CONSTANT; 719 b_op->op_data = cnst; 720 b_op->next = NULL; 721 append_op (bi, b_op); 722} 723 724 725static void 726append_field_op (BuildInstr *bi, unsigned op1, unsigned src_op) 727{ 728 BuildOp *b_op = XNEW (BuildOp); 729 730 b_op->op_num = op1; 731 b_op->typ = OP_OPERAND; 732 b_op->op_data = src_op; 733 b_op->next = NULL; 734 append_op (bi, b_op); 735} 736 737 738/* These could be generated but are not currently. */ 739 740static void 741append_user_fn_field_op (BuildInstr *bi, 742 unsigned op1, 743 OpType typ, 744 unsigned src_op) 745{ 746 BuildOp *b_op = XNEW (BuildOp); 747 748 b_op->op_num = op1; 749 b_op->typ = typ; 750 b_op->op_data = src_op; 751 b_op->next = NULL; 752 append_op (bi, b_op); 753} 754 755 756/* These operand functions are the semantics of user-defined 757 operand functions. */ 758 759static long 760operand_function_HI24S (long a) 761{ 762 if (a & 0x80) 763 return (a & (~0xff)) + 0x100; 764 else 765 return (a & (~0xff)); 766} 767 768 769static long 770operand_function_F32MINUS (long a) 771{ 772 return (32 - a); 773} 774 775 776static long 777operand_function_LOW8 (long a) 778{ 779 if (a & 0x80) 780 return (a & 0xff) | ~0xff; 781 else 782 return (a & 0xff); 783} 784 785 786static long 787operand_function_LOW16U (long a) 788{ 789 return (a & 0xffff); 790} 791 792 793static long 794operand_function_HI16U (long a) 795{ 796 unsigned long b = a & 0xffff0000; 797 return (long) (b >> 16); 798} 799 800 801bool 802xg_has_userdef_op_fn (OpType op) 803{ 804 switch (op) 805 { 806 case OP_OPERAND_F32MINUS: 807 case OP_OPERAND_LOW8: 808 case OP_OPERAND_HI24S: 809 case OP_OPERAND_LOW16U: 810 case OP_OPERAND_HI16U: 811 return true; 812 default: 813 break; 814 } 815 return false; 816} 817 818 819long 820xg_apply_userdef_op_fn (OpType op, long a) 821{ 822 switch (op) 823 { 824 case OP_OPERAND_F32MINUS: 825 return operand_function_F32MINUS (a); 826 case OP_OPERAND_LOW8: 827 return operand_function_LOW8 (a); 828 case OP_OPERAND_HI24S: 829 return operand_function_HI24S (a); 830 case OP_OPERAND_LOW16U: 831 return operand_function_LOW16U (a); 832 case OP_OPERAND_HI16U: 833 return operand_function_HI16U (a); 834 default: 835 break; 836 } 837 return false; 838} 839 840 841/* Generate a transition table. */ 842 843static const char * 844enter_opname_n (const char *name, int len) 845{ 846 opname_e *op; 847 848 for (op = local_opnames; op != NULL; op = op->next) 849 { 850 if (strlen (op->opname) == (unsigned) len 851 && strncmp (op->opname, name, len) == 0) 852 return op->opname; 853 } 854 op = XNEW (opname_e); 855 op->opname = xmemdup0 (name, len); 856 return op->opname; 857} 858 859 860static const char * 861enter_opname (const char *name) 862{ 863 opname_e *op; 864 865 for (op = local_opnames; op != NULL; op = op->next) 866 { 867 if (strcmp (op->opname, name) == 0) 868 return op->opname; 869 } 870 op = XNEW (opname_e); 871 op->opname = xstrdup (name); 872 return op->opname; 873} 874 875 876static void 877init_opname_map (opname_map *m) 878{ 879 m->head = NULL; 880 m->tail = &m->head; 881} 882 883 884static void 885clear_opname_map (opname_map *m) 886{ 887 opname_map_e *e; 888 889 while (m->head != NULL) 890 { 891 e = m->head; 892 m->head = e->next; 893 free (e); 894 } 895 m->tail = &m->head; 896} 897 898 899static bool 900same_operand_name (const opname_map_e *m1, const opname_map_e *m2) 901{ 902 if (m1->operand_name == NULL || m2->operand_name == NULL) 903 return false; 904 return (m1->operand_name == m2->operand_name); 905} 906 907 908static opname_map_e * 909get_opmatch (opname_map *map, const char *operand_name) 910{ 911 opname_map_e *m; 912 913 for (m = map->head; m != NULL; m = m->next) 914 { 915 if (strcmp (m->operand_name, operand_name) == 0) 916 return m; 917 } 918 return NULL; 919} 920 921 922static bool 923op_is_constant (const opname_map_e *m1) 924{ 925 return (m1->operand_name == NULL); 926} 927 928 929static unsigned 930op_get_constant (const opname_map_e *m1) 931{ 932 gas_assert (m1->operand_name == NULL); 933 return m1->constant_value; 934} 935 936 937static void 938init_precond_list (precond_list *l) 939{ 940 l->head = NULL; 941 l->tail = &l->head; 942} 943 944 945static void 946clear_precond_list (precond_list *l) 947{ 948 precond_e *e; 949 950 while (l->head != NULL) 951 { 952 e = l->head; 953 l->head = e->next; 954 free (e); 955 } 956 l->tail = &l->head; 957} 958 959 960static void 961init_insn_templ (insn_templ *t) 962{ 963 t->opcode_name = NULL; 964 init_opname_map (&t->operand_map); 965} 966 967 968static void 969clear_insn_templ (insn_templ *t) 970{ 971 clear_opname_map (&t->operand_map); 972} 973 974 975static void 976init_insn_pattern (insn_pattern *p) 977{ 978 init_insn_templ (&p->t); 979 init_precond_list (&p->preconds); 980 p->options = NULL; 981} 982 983 984static void 985clear_insn_pattern (insn_pattern *p) 986{ 987 clear_insn_templ (&p->t); 988 clear_precond_list (&p->preconds); 989} 990 991 992static void 993init_insn_repl (insn_repl *r) 994{ 995 r->head = NULL; 996 r->tail = &r->head; 997} 998 999 1000static void 1001clear_insn_repl (insn_repl *r) 1002{ 1003 insn_repl_e *e; 1004 1005 while (r->head != NULL) 1006 { 1007 e = r->head; 1008 r->head = e->next; 1009 clear_insn_templ (&e->t); 1010 } 1011 r->tail = &r->head; 1012} 1013 1014 1015static int 1016insn_templ_operand_count (const insn_templ *t) 1017{ 1018 int i = 0; 1019 const opname_map_e *op; 1020 1021 for (op = t->operand_map.head; op != NULL; op = op->next, i++) 1022 ; 1023 return i; 1024} 1025 1026 1027/* Convert a string to a number. E.G.: parse_constant("10", &num) */ 1028 1029static bool 1030parse_constant (const char *in, unsigned *val_p) 1031{ 1032 unsigned val = 0; 1033 const char *p; 1034 1035 if (in == NULL) 1036 return false; 1037 p = in; 1038 1039 while (*p != '\0') 1040 { 1041 if (*p >= '0' && *p <= '9') 1042 val = val * 10 + (*p - '0'); 1043 else 1044 return false; 1045 ++p; 1046 } 1047 *val_p = val; 1048 return true; 1049} 1050 1051 1052static bool 1053parse_special_fn (const char *name, 1054 const char **fn_name_p, 1055 const char **arg_name_p) 1056{ 1057 const char *p_start; 1058 const char *p_end; 1059 1060 p_start = strchr (name, '('); 1061 if (p_start == NULL) 1062 return false; 1063 1064 p_end = strchr (p_start, ')'); 1065 1066 if (p_end == NULL) 1067 return false; 1068 1069 if (p_end[1] != '\0') 1070 return false; 1071 1072 *fn_name_p = enter_opname_n (name, p_start - name); 1073 *arg_name_p = enter_opname_n (p_start + 1, p_end - p_start - 1); 1074 return true; 1075} 1076 1077 1078static const char * 1079skip_white (const char *p) 1080{ 1081 if (p == NULL) 1082 return p; 1083 while (*p == ' ') 1084 ++p; 1085 return p; 1086} 1087 1088 1089static void 1090trim_whitespace (char *in) 1091{ 1092 char *last_white = NULL; 1093 char *p = in; 1094 1095 while (p && *p != '\0') 1096 { 1097 while (*p == ' ') 1098 { 1099 if (last_white == NULL) 1100 last_white = p; 1101 p++; 1102 } 1103 if (*p != '\0') 1104 { 1105 last_white = NULL; 1106 p++; 1107 } 1108 } 1109 if (last_white) 1110 *last_white = '\0'; 1111} 1112 1113 1114/* Split a string into component strings where "c" is the 1115 delimiter. Place the result in the split_rec. */ 1116 1117static void 1118split_string (split_rec *rec, 1119 const char *in, 1120 char c, 1121 bool elide_whitespace) 1122{ 1123 int cnt = 0; 1124 int i; 1125 const char *p = in; 1126 1127 while (p != NULL && *p != '\0') 1128 { 1129 cnt++; 1130 p = strchr (p, c); 1131 if (p) 1132 p++; 1133 } 1134 rec->count = cnt; 1135 rec->vec = NULL; 1136 1137 if (rec->count == 0) 1138 return; 1139 1140 rec->vec = XNEWVEC (char *, cnt); 1141 for (i = 0; i < cnt; i++) 1142 rec->vec[i] = 0; 1143 1144 p = in; 1145 for (i = 0; i < cnt; i++) 1146 { 1147 const char *q; 1148 int len; 1149 1150 q = p; 1151 if (elide_whitespace) 1152 q = skip_white (q); 1153 1154 p = strchr (q, c); 1155 if (p == NULL) 1156 rec->vec[i] = xstrdup (q); 1157 else 1158 { 1159 len = p - q; 1160 rec->vec[i] = xmemdup0 (q, len); 1161 p++; 1162 } 1163 1164 if (elide_whitespace) 1165 trim_whitespace (rec->vec[i]); 1166 } 1167} 1168 1169 1170static void 1171clear_split_rec (split_rec *rec) 1172{ 1173 int i; 1174 1175 for (i = 0; i < rec->count; i++) 1176 free (rec->vec[i]); 1177 1178 if (rec->count > 0) 1179 free (rec->vec); 1180} 1181 1182 1183/* Initialize a split record. The split record must be initialized 1184 before split_string is called. */ 1185 1186static void 1187init_split_rec (split_rec *rec) 1188{ 1189 rec->vec = NULL; 1190 rec->count = 0; 1191} 1192 1193 1194/* Parse an instruction template like "insn op1, op2, op3". */ 1195 1196static bool 1197parse_insn_templ (const char *s, insn_templ *t) 1198{ 1199 const char *p = s; 1200 int insn_name_len; 1201 split_rec oprec; 1202 int i; 1203 1204 /* First find the first whitespace. */ 1205 1206 init_split_rec (&oprec); 1207 1208 p = skip_white (p); 1209 insn_name_len = strcspn (s, " "); 1210 if (insn_name_len == 0) 1211 return false; 1212 1213 init_insn_templ (t); 1214 t->opcode_name = enter_opname_n (p, insn_name_len); 1215 1216 p = p + insn_name_len; 1217 1218 /* Split by ',' and skip beginning and trailing whitespace. */ 1219 split_string (&oprec, p, ',', true); 1220 1221 for (i = 0; i < oprec.count; i++) 1222 { 1223 const char *opname = oprec.vec[i]; 1224 opname_map_e *e = XNEW (opname_map_e); 1225 e->next = NULL; 1226 e->operand_name = NULL; 1227 e->constant_value = 0; 1228 e->operand_num = i; 1229 1230 /* If it begins with a number, assume that it is a number. */ 1231 if (opname && opname[0] >= '0' && opname[0] <= '9') 1232 { 1233 unsigned val; 1234 1235 if (parse_constant (opname, &val)) 1236 e->constant_value = val; 1237 else 1238 { 1239 free (e); 1240 clear_split_rec (&oprec); 1241 clear_insn_templ (t); 1242 return false; 1243 } 1244 } 1245 else 1246 e->operand_name = enter_opname (oprec.vec[i]); 1247 1248 *t->operand_map.tail = e; 1249 t->operand_map.tail = &e->next; 1250 } 1251 clear_split_rec (&oprec); 1252 return true; 1253} 1254 1255 1256static bool 1257parse_precond (const char *s, precond_e *precond) 1258{ 1259 /* All preconditions are currently of the form: 1260 a == b or a != b or a == k (where k is a constant). 1261 Later we may use some special functions like DENSITY == 1 1262 to identify when density is available. */ 1263 1264 const char *p = s; 1265 int len; 1266 precond->opname1 = NULL; 1267 precond->opval1 = 0; 1268 precond->cmpop = OP_EQUAL; 1269 precond->opname2 = NULL; 1270 precond->opval2 = 0; 1271 precond->next = NULL; 1272 1273 p = skip_white (p); 1274 1275 len = strcspn (p, " !="); 1276 1277 if (len == 0) 1278 return false; 1279 1280 precond->opname1 = enter_opname_n (p, len); 1281 p = p + len; 1282 p = skip_white (p); 1283 1284 /* Check for "==" and "!=". */ 1285 if (startswith (p, "==")) 1286 precond->cmpop = OP_EQUAL; 1287 else if (startswith (p, "!=")) 1288 precond->cmpop = OP_NOTEQUAL; 1289 else 1290 return false; 1291 1292 p = p + 2; 1293 p = skip_white (p); 1294 1295 /* No trailing whitespace from earlier parsing. */ 1296 if (p[0] >= '0' && p[0] <= '9') 1297 { 1298 unsigned val; 1299 if (parse_constant (p, &val)) 1300 precond->opval2 = val; 1301 else 1302 return false; 1303 } 1304 else 1305 precond->opname2 = enter_opname (p); 1306 return true; 1307} 1308 1309 1310static void 1311clear_req_or_option_list (ReqOrOption **r_p) 1312{ 1313 if (*r_p == NULL) 1314 return; 1315 1316 free ((*r_p)->option_name); 1317 clear_req_or_option_list (&(*r_p)->next); 1318 *r_p = NULL; 1319} 1320 1321 1322static void 1323clear_req_option_list (ReqOption **r_p) 1324{ 1325 if (*r_p == NULL) 1326 return; 1327 1328 clear_req_or_option_list (&(*r_p)->or_option_terms); 1329 clear_req_option_list (&(*r_p)->next); 1330 *r_p = NULL; 1331} 1332 1333 1334static ReqOrOption * 1335clone_req_or_option_list (ReqOrOption *req_or_option) 1336{ 1337 ReqOrOption *new_req_or_option; 1338 1339 if (req_or_option == NULL) 1340 return NULL; 1341 1342 new_req_or_option = XNEW (ReqOrOption); 1343 new_req_or_option->option_name = xstrdup (req_or_option->option_name); 1344 new_req_or_option->is_true = req_or_option->is_true; 1345 new_req_or_option->next = NULL; 1346 new_req_or_option->next = clone_req_or_option_list (req_or_option->next); 1347 return new_req_or_option; 1348} 1349 1350 1351static ReqOption * 1352clone_req_option_list (ReqOption *req_option) 1353{ 1354 ReqOption *new_req_option; 1355 1356 if (req_option == NULL) 1357 return NULL; 1358 1359 new_req_option = XNEW (ReqOption); 1360 new_req_option->or_option_terms = NULL; 1361 new_req_option->next = NULL; 1362 new_req_option->or_option_terms = 1363 clone_req_or_option_list (req_option->or_option_terms); 1364 new_req_option->next = clone_req_option_list (req_option->next); 1365 return new_req_option; 1366} 1367 1368 1369static bool 1370parse_option_cond (const char *s, ReqOption *option) 1371{ 1372 int i; 1373 split_rec option_term_rec; 1374 1375 /* All option or conditions are of the form: 1376 optionA + no-optionB + ... 1377 "Ands" are divided by "?". */ 1378 1379 init_split_rec (&option_term_rec); 1380 split_string (&option_term_rec, s, '+', true); 1381 1382 if (option_term_rec.count == 0) 1383 { 1384 clear_split_rec (&option_term_rec); 1385 return false; 1386 } 1387 1388 for (i = 0; i < option_term_rec.count; i++) 1389 { 1390 char *option_name = option_term_rec.vec[i]; 1391 bool is_true = true; 1392 ReqOrOption *req; 1393 ReqOrOption **r_p; 1394 1395 if (startswith (option_name, "no-")) 1396 { 1397 option_name = xstrdup (&option_name[3]); 1398 is_true = false; 1399 } 1400 else 1401 option_name = xstrdup (option_name); 1402 1403 req = XNEW (ReqOrOption); 1404 req->option_name = option_name; 1405 req->is_true = is_true; 1406 req->next = NULL; 1407 1408 /* Append to list. */ 1409 for (r_p = &option->or_option_terms; (*r_p) != NULL; 1410 r_p = &(*r_p)->next) 1411 ; 1412 (*r_p) = req; 1413 } 1414 return true; 1415} 1416 1417 1418/* Parse a string like: 1419 "insn op1, op2, op3, op4 | op1 != op2 | op2 == op3 | op4 == 1". 1420 I.E., instruction "insn" with 4 operands where operand 1 and 2 are not 1421 the same and operand 2 and 3 are the same and operand 4 is 1. 1422 1423 or: 1424 1425 "insn op1 | op1 == 1 / density + boolean / no-useroption". 1426 i.e. instruction "insn" with 1 operands where operand 1 is 1 1427 when "density" or "boolean" options are available and 1428 "useroption" is not available. 1429 1430 Because the current implementation of this parsing scheme uses 1431 split_string, it requires that '|' and '?' are only used as 1432 delimiters for predicates and required options. */ 1433 1434static bool 1435parse_insn_pattern (const char *in, insn_pattern *insn) 1436{ 1437 split_rec rec; 1438 split_rec optionrec; 1439 int i; 1440 1441 init_insn_pattern (insn); 1442 1443 init_split_rec (&optionrec); 1444 split_string (&optionrec, in, '?', true); 1445 if (optionrec.count == 0) 1446 { 1447 clear_split_rec (&optionrec); 1448 return false; 1449 } 1450 1451 init_split_rec (&rec); 1452 1453 split_string (&rec, optionrec.vec[0], '|', true); 1454 1455 if (rec.count == 0) 1456 { 1457 clear_split_rec (&rec); 1458 clear_split_rec (&optionrec); 1459 return false; 1460 } 1461 1462 if (!parse_insn_templ (rec.vec[0], &insn->t)) 1463 { 1464 clear_split_rec (&rec); 1465 clear_split_rec (&optionrec); 1466 return false; 1467 } 1468 1469 for (i = 1; i < rec.count; i++) 1470 { 1471 precond_e *cond = XNEW (precond_e); 1472 1473 if (!parse_precond (rec.vec[i], cond)) 1474 { 1475 clear_split_rec (&rec); 1476 clear_split_rec (&optionrec); 1477 clear_insn_pattern (insn); 1478 return false; 1479 } 1480 1481 /* Append the condition. */ 1482 *insn->preconds.tail = cond; 1483 insn->preconds.tail = &cond->next; 1484 } 1485 1486 for (i = 1; i < optionrec.count; i++) 1487 { 1488 /* Handle the option conditions. */ 1489 ReqOption **r_p; 1490 ReqOption *req_option = XNEW (ReqOption); 1491 req_option->or_option_terms = NULL; 1492 req_option->next = NULL; 1493 1494 if (!parse_option_cond (optionrec.vec[i], req_option)) 1495 { 1496 clear_split_rec (&rec); 1497 clear_split_rec (&optionrec); 1498 clear_insn_pattern (insn); 1499 clear_req_option_list (&req_option); 1500 return false; 1501 } 1502 1503 /* Append the condition. */ 1504 for (r_p = &insn->options; (*r_p) != NULL; r_p = &(*r_p)->next) 1505 ; 1506 1507 (*r_p) = req_option; 1508 } 1509 1510 clear_split_rec (&rec); 1511 clear_split_rec (&optionrec); 1512 return true; 1513} 1514 1515 1516static bool 1517parse_insn_repl (const char *in, insn_repl *r_p) 1518{ 1519 /* This is a list of instruction templates separated by ';'. */ 1520 split_rec rec; 1521 int i; 1522 1523 split_string (&rec, in, ';', true); 1524 1525 for (i = 0; i < rec.count; i++) 1526 { 1527 insn_repl_e *e = XNEW (insn_repl_e); 1528 1529 e->next = NULL; 1530 1531 if (!parse_insn_templ (rec.vec[i], &e->t)) 1532 { 1533 free (e); 1534 clear_insn_repl (r_p); 1535 return false; 1536 } 1537 *r_p->tail = e; 1538 r_p->tail = &e->next; 1539 } 1540 return true; 1541} 1542 1543 1544static bool 1545transition_applies (insn_pattern *initial_insn, 1546 const char *from_string ATTRIBUTE_UNUSED, 1547 const char *to_string ATTRIBUTE_UNUSED) 1548{ 1549 ReqOption *req_option; 1550 1551 for (req_option = initial_insn->options; 1552 req_option != NULL; 1553 req_option = req_option->next) 1554 { 1555 ReqOrOption *req_or_option = req_option->or_option_terms; 1556 1557 if (req_or_option == NULL 1558 || req_or_option->next != NULL) 1559 continue; 1560 1561 if (startswith (req_or_option->option_name, "IsaUse")) 1562 { 1563 bool option_available = false; 1564 char *option_name = req_or_option->option_name + 6; 1565 if (!strcmp (option_name, "DensityInstruction")) 1566 option_available = (XCHAL_HAVE_DENSITY == 1); 1567 else if (!strcmp (option_name, "L32R")) 1568 option_available = (XCHAL_HAVE_L32R == 1); 1569 else if (!strcmp (option_name, "Const16")) 1570 option_available = (XCHAL_HAVE_CONST16 == 1); 1571 else if (!strcmp (option_name, "Loops")) 1572 option_available = (XCHAL_HAVE_LOOPS == 1); 1573 else if (!strcmp (option_name, "WideBranches")) 1574 option_available 1575 = (XCHAL_HAVE_WIDE_BRANCHES == 1 && produce_flix == FLIX_ALL); 1576 else if (!strcmp (option_name, "PredictedBranches")) 1577 option_available 1578 = (XCHAL_HAVE_PREDICTED_BRANCHES == 1 1579 && produce_flix == FLIX_ALL); 1580 else if (!strcmp (option_name, "Booleans")) 1581 option_available = (XCHAL_HAVE_BOOLEANS == 1); 1582 else 1583 as_warn (_("invalid configuration option '%s' in transition rule '%s'"), 1584 req_or_option->option_name, from_string); 1585 if ((option_available ^ req_or_option->is_true) != 0) 1586 return false; 1587 } 1588 else if (strcmp (req_or_option->option_name, "realnop") == 0) 1589 { 1590 bool nop_available = 1591 (xtensa_opcode_lookup (xtensa_default_isa, "nop") 1592 != XTENSA_UNDEFINED); 1593 if ((nop_available ^ req_or_option->is_true) != 0) 1594 return false; 1595 } 1596 } 1597 return true; 1598} 1599 1600 1601static bool 1602wide_branch_opcode (const char *opcode_name, 1603 const char *suffix, 1604 xtensa_opcode *popcode) 1605{ 1606 xtensa_isa isa = xtensa_default_isa; 1607 xtensa_opcode opcode; 1608 static char wbr_name_buf[20]; 1609 1610 if (!startswith (opcode_name, "WIDE.")) 1611 return false; 1612 1613 strcpy (wbr_name_buf, opcode_name + 5); 1614 strcat (wbr_name_buf, suffix); 1615 opcode = xtensa_opcode_lookup (isa, wbr_name_buf); 1616 if (opcode != XTENSA_UNDEFINED) 1617 { 1618 *popcode = opcode; 1619 return true; 1620 } 1621 1622 return false; 1623} 1624 1625 1626static TransitionRule * 1627build_transition (insn_pattern *initial_insn, 1628 insn_repl *replace_insns, 1629 const char *from_string, 1630 const char *to_string) 1631{ 1632 TransitionRule *tr = NULL; 1633 xtensa_opcode opcode; 1634 xtensa_isa isa = xtensa_default_isa; 1635 BuildInstr *literal_bi; 1636 1637 opname_map_e *op1; 1638 opname_map_e *op2; 1639 1640 precond_e *precond; 1641 insn_repl_e *r; 1642 1643 if (!wide_branch_opcode (initial_insn->t.opcode_name, ".w18", &opcode) 1644 && !wide_branch_opcode (initial_insn->t.opcode_name, ".w15", &opcode)) 1645 opcode = xtensa_opcode_lookup (isa, initial_insn->t.opcode_name); 1646 1647 if (opcode == XTENSA_UNDEFINED) 1648 { 1649 /* It is OK to not be able to translate some of these opcodes. */ 1650 return NULL; 1651 } 1652 1653 1654 if (xtensa_opcode_num_operands (isa, opcode) 1655 != insn_templ_operand_count (&initial_insn->t)) 1656 { 1657 /* This is also OK because there are opcodes that 1658 have different numbers of operands on different 1659 architecture variations. */ 1660 return NULL; 1661 } 1662 1663 tr = XNEW (TransitionRule); 1664 tr->opcode = opcode; 1665 tr->conditions = NULL; 1666 tr->to_instr = NULL; 1667 1668 /* Build the conditions. First, equivalent operand condition.... */ 1669 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next) 1670 { 1671 for (op2 = op1->next; op2 != NULL; op2 = op2->next) 1672 { 1673 if (same_operand_name (op1, op2)) 1674 { 1675 append_value_condition (tr, OP_EQUAL, 1676 op1->operand_num, op2->operand_num); 1677 } 1678 } 1679 } 1680 1681 /* Now the condition that an operand value must be a constant.... */ 1682 for (op1 = initial_insn->t.operand_map.head; op1 != NULL; op1 = op1->next) 1683 { 1684 if (op_is_constant (op1)) 1685 { 1686 append_constant_value_condition (tr, 1687 OP_EQUAL, 1688 op1->operand_num, 1689 op_get_constant (op1)); 1690 } 1691 } 1692 1693 1694 /* Now add the explicit preconditions listed after the "|" in the spec. 1695 These are currently very limited, so we do a special case 1696 parse for them. We expect spaces, opname != opname. */ 1697 for (precond = initial_insn->preconds.head; 1698 precond != NULL; 1699 precond = precond->next) 1700 { 1701 op1 = NULL; 1702 op2 = NULL; 1703 1704 if (precond->opname1) 1705 { 1706 op1 = get_opmatch (&initial_insn->t.operand_map, precond->opname1); 1707 if (op1 == NULL) 1708 as_fatal (_("opcode '%s': no bound opname '%s' " 1709 "for precondition in '%s'"), 1710 xtensa_opcode_name (isa, opcode), 1711 precond->opname1, from_string); 1712 } 1713 1714 if (precond->opname2) 1715 { 1716 op2 = get_opmatch (&initial_insn->t.operand_map, precond->opname2); 1717 if (op2 == NULL) 1718 as_fatal (_("opcode '%s': no bound opname '%s' " 1719 "for precondition in '%s'"), 1720 xtensa_opcode_name (isa, opcode), 1721 precond->opname2, from_string); 1722 } 1723 1724 if (op1 == NULL && op2 == NULL) 1725 as_fatal (_("opcode '%s': precondition only contains " 1726 "constants in '%s'"), 1727 xtensa_opcode_name (isa, opcode), from_string); 1728 else if (op1 != NULL && op2 != NULL) 1729 append_value_condition (tr, precond->cmpop, 1730 op1->operand_num, op2->operand_num); 1731 else if (op2 == NULL) 1732 append_constant_value_condition (tr, precond->cmpop, 1733 op1->operand_num, precond->opval2); 1734 else 1735 append_constant_value_condition (tr, precond->cmpop, 1736 op2->operand_num, precond->opval1); 1737 } 1738 1739 tr->options = clone_req_option_list (initial_insn->options); 1740 1741 /* Generate the replacement instructions. Some of these 1742 "instructions" are actually labels and literals. There can be at 1743 most one literal and at most one label. A literal must be defined 1744 (e.g., "LITERAL %imm") before use (e.g., "%LITERAL"). The labels 1745 can be used before they are defined. Also there are a number of 1746 special operands (e.g., HI24S). */ 1747 1748 literal_bi = NULL; 1749 for (r = replace_insns->head; r != NULL; r = r->next) 1750 { 1751 BuildInstr *bi; 1752 const char *opcode_name; 1753 int operand_count; 1754 opname_map_e *op; 1755 const char *fn_name; 1756 const char *operand_arg_name; 1757 1758 bi = XNEW (BuildInstr); 1759 append_build_insn (tr, bi); 1760 1761 bi->opcode = XTENSA_UNDEFINED; 1762 bi->ops = NULL; 1763 bi->next = NULL; 1764 1765 opcode_name = r->t.opcode_name; 1766 operand_count = insn_templ_operand_count (&r->t); 1767 1768 if (strcmp (opcode_name, "LITERAL") == 0) 1769 { 1770 bi->typ = INSTR_LITERAL_DEF; 1771 if (operand_count != 1) 1772 as_fatal (_("expected one operand for generated literal")); 1773 literal_bi = bi; 1774 } 1775 else if (strcmp (opcode_name, "LABEL") == 0) 1776 { 1777 bi->typ = INSTR_LABEL_DEF; 1778 if (operand_count != 0) 1779 as_fatal (_("expected 0 operands for generated label")); 1780 } 1781 else 1782 { 1783 bi->typ = INSTR_INSTR; 1784 if (wide_branch_opcode (opcode_name, ".w18", &bi->opcode) 1785 || wide_branch_opcode (opcode_name, ".w15", &bi->opcode)) 1786 opcode_name = xtensa_opcode_name (isa, bi->opcode); 1787 else 1788 bi->opcode = xtensa_opcode_lookup (isa, opcode_name); 1789 1790 if (bi->opcode == XTENSA_UNDEFINED) 1791 { 1792 as_warn (_("invalid opcode '%s' in transition rule '%s'"), 1793 opcode_name, to_string); 1794 return NULL; 1795 } 1796 1797 /* Check for the right number of ops. */ 1798 if (xtensa_opcode_num_operands (isa, bi->opcode) 1799 != (int) operand_count) 1800 as_fatal (ngettext ("opcode '%s': replacement does not have %d op", 1801 "opcode '%s': replacement does not have %d ops", 1802 xtensa_opcode_num_operands (isa, bi->opcode)), 1803 opcode_name, 1804 xtensa_opcode_num_operands (isa, bi->opcode)); 1805 } 1806 1807 for (op = r->t.operand_map.head; op != NULL; op = op->next) 1808 { 1809 unsigned idnum; 1810 1811 if (op_is_constant (op)) 1812 append_constant_op (bi, op->operand_num, op_get_constant (op)); 1813 else if (strcmp (op->operand_name, "%LITERAL") == 0) 1814 { 1815 if (! literal_bi || ! literal_bi->ops || literal_bi->ops->next) 1816 as_fatal (_("opcode '%s': cannot find literal definition"), 1817 opcode_name); 1818 append_literal_op (bi, op->operand_num, 1819 literal_bi->ops->op_data); 1820 } 1821 else if (strcmp (op->operand_name, "%LABEL") == 0) 1822 append_label_op (bi, op->operand_num); 1823 else if (op->operand_name[0] == 'a' 1824 && parse_constant (op->operand_name + 1, &idnum)) 1825 append_constant_op (bi, op->operand_num, idnum); 1826 else if (op->operand_name[0] == '%') 1827 { 1828 opname_map_e *orig_op; 1829 orig_op = get_opmatch (&initial_insn->t.operand_map, 1830 op->operand_name); 1831 if (orig_op == NULL) 1832 as_fatal (_("opcode '%s': unidentified operand '%s' in '%s'"), 1833 opcode_name, op->operand_name, to_string); 1834 append_field_op (bi, op->operand_num, orig_op->operand_num); 1835 } 1836 else if (strcmp (op->operand_name, "FREEREG") == 0) 1837 { 1838 append_user_fn_field_op (bi, op->operand_num, OP_FREEREG, 0); 1839 } 1840 else if (parse_special_fn (op->operand_name, 1841 &fn_name, &operand_arg_name)) 1842 { 1843 opname_map_e *orig_op; 1844 OpType typ = OP_CONSTANT; 1845 1846 if (strcmp (fn_name, "LOW8") == 0) 1847 typ = OP_OPERAND_LOW8; 1848 else if (strcmp (fn_name, "HI24S") == 0) 1849 typ = OP_OPERAND_HI24S; 1850 else if (strcmp (fn_name, "F32MINUS") == 0) 1851 typ = OP_OPERAND_F32MINUS; 1852 else if (strcmp (fn_name, "LOW16U") == 0) 1853 typ = OP_OPERAND_LOW16U; 1854 else if (strcmp (fn_name, "HI16U") == 0) 1855 typ = OP_OPERAND_HI16U; 1856 else 1857 as_fatal (_("unknown user-defined function %s"), fn_name); 1858 1859 orig_op = get_opmatch (&initial_insn->t.operand_map, 1860 operand_arg_name); 1861 if (orig_op == NULL) 1862 as_fatal (_("opcode '%s': unidentified operand '%s' in '%s'"), 1863 opcode_name, op->operand_name, to_string); 1864 append_user_fn_field_op (bi, op->operand_num, 1865 typ, orig_op->operand_num); 1866 } 1867 else 1868 as_fatal (_("opcode '%s': could not parse operand '%s' in '%s'"), 1869 opcode_name, op->operand_name, to_string); 1870 } 1871 } 1872 1873 return tr; 1874} 1875 1876 1877static TransitionTable * 1878build_transition_table (const string_pattern_pair *transitions, 1879 int transition_count, 1880 transition_cmp_fn cmp) 1881{ 1882 TransitionTable *table = NULL; 1883 int num_opcodes = xtensa_isa_num_opcodes (xtensa_default_isa); 1884 int i, tnum; 1885 1886 if (table != NULL) 1887 return table; 1888 1889 /* Otherwise, build it now. */ 1890 table = XNEW (TransitionTable); 1891 table->num_opcodes = num_opcodes; 1892 table->table = XNEWVEC (TransitionList *, num_opcodes); 1893 1894 for (i = 0; i < num_opcodes; i++) 1895 table->table[i] = NULL; 1896 1897 for (tnum = 0; tnum < transition_count; tnum++) 1898 { 1899 const char *from_string = transitions[tnum].pattern; 1900 const char *to_string = transitions[tnum].replacement; 1901 1902 insn_pattern initial_insn; 1903 insn_repl replace_insns; 1904 TransitionRule *tr; 1905 1906 init_insn_pattern (&initial_insn); 1907 if (!parse_insn_pattern (from_string, &initial_insn)) 1908 as_fatal (_("could not parse INSN_PATTERN '%s'"), from_string); 1909 1910 init_insn_repl (&replace_insns); 1911 if (!parse_insn_repl (to_string, &replace_insns)) 1912 as_fatal (_("could not parse INSN_REPL '%s'"), to_string); 1913 1914 if (transition_applies (&initial_insn, from_string, to_string)) 1915 { 1916 tr = build_transition (&initial_insn, &replace_insns, 1917 from_string, to_string); 1918 if (tr) 1919 append_transition (table, tr->opcode, tr, cmp); 1920 else 1921 { 1922#if TENSILICA_DEBUG 1923 as_warn (_("could not build transition for %s => %s"), 1924 from_string, to_string); 1925#endif 1926 } 1927 } 1928 1929 clear_insn_repl (&replace_insns); 1930 clear_insn_pattern (&initial_insn); 1931 } 1932 return table; 1933} 1934 1935 1936extern TransitionTable * 1937xg_build_widen_table (transition_cmp_fn cmp) 1938{ 1939 static TransitionTable *table = NULL; 1940 if (table == NULL) 1941 table = build_transition_table (widen_spec_list, WIDEN_COUNT, cmp); 1942 return table; 1943} 1944 1945 1946extern TransitionTable * 1947xg_build_simplify_table (transition_cmp_fn cmp) 1948{ 1949 static TransitionTable *table = NULL; 1950 if (table == NULL) 1951 table = build_transition_table (simplify_spec_list, SIMPLIFY_COUNT, cmp); 1952 return table; 1953} 1954