X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-vax.c;h=5634566945b821a2239ee776f37e3fd4a46db5bf;hb=ec40e91c77ecf4ca853577aa7d68bdaf5aeedfd5;hp=e7a7c34d5e0199e818ad835529d61f3c656dffbb;hpb=9c2799c243988c1a6d3fe93c7c2c06599672068d;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-vax.c b/gas/config/tc-vax.c index e7a7c34d5e..5634566945 100644 --- a/gas/config/tc-vax.c +++ b/gas/config/tc-vax.c @@ -1,7 +1,5 @@ /* tc-vax.c - vax-specific - - Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1998, 2000, 2001, 2002, - 2003, 2004, 2005, 2006, 2007, 2008 - Free Software Foundation, Inc. + Copyright (C) 1987-2020 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -129,7 +127,7 @@ int flag_want_pic; /* -k */ bbsc e4 bbcc e5 Always, you complement 0th bit to reverse condition. - Always, 1-byte opcde, longword-address, byte-address, 1-byte-displacement + Always, 1-byte opcode, longword-address, byte-address, 1-byte-displacement 2c. J where cond tests low-order memory bit length of byte,word,long. @@ -190,7 +188,7 @@ int flag_want_pic; /* -k */ #define BB (1+-128) #define WF (2+ 32767) #define WB (2+-32768) -/* Dont need LF, LB because they always reach. [They are coded as 0.] */ +/* Don't need LF, LB because they always reach. [They are coded as 0.] */ #define C(a,b) ENCODE_RELAX(a,b) /* This macro has no side-effects. */ @@ -238,7 +236,7 @@ const relax_typeS md_relax_table[] = #undef WB void float_cons (int); -int flonum_gen2vax (char, FLONUM_TYPE *, LITTLENUM_TYPE *); +int flonum_gen2vax (int, FLONUM_TYPE *, LITTLENUM_TYPE *); const pseudo_typeS md_pseudo_table[] = { @@ -280,15 +278,21 @@ md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED) { valueT value = * valueP; - if (((fixP->fx_addsy == NULL && fixP->fx_subsy == NULL) - && fixP->fx_r_type != BFD_RELOC_32_PLT_PCREL - && fixP->fx_r_type != BFD_RELOC_32_GOT_PCREL) - || fixP->fx_r_type == NO_RELOC) - number_to_chars_littleendian (fixP->fx_where + fixP->fx_frag->fr_literal, - value, fixP->fx_size); + if (fixP->fx_subsy != (symbolS *) NULL) + as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex")); - if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) + if (fixP->fx_addsy == NULL) fixP->fx_done = 1; + + if (fixP->fx_done) + number_to_chars_littleendian (fixP->fx_where + fixP->fx_frag->fr_literal, + value, fixP->fx_size); + else + /* Initialise the part of an instruction frag covered by the + relocation. (Many occurrences of frag_more followed by fix_new + lack any init of the frag.) Since VAX uses RELA relocs the + value we write into this field doesn't really matter. */ + memset (fixP->fx_where + fixP->fx_frag->fr_literal, 0, fixP->fx_size); } /* Convert a number from VAX byte order (little endian) @@ -779,11 +783,11 @@ static const short int vax_operand_width_size[256] = ban these opcodes. They are mnemonics for "elastic" instructions that are supposed to assemble into the fewest bytes needed to do a branch, or to do a conditional branch, or whatever. - + The opcode is in the usual place [low-order n*8 bits]. This means that if you mask off the bucky bits, the usual rules apply about how long the opcode is. - + All VAX branch displacements come at the end of the instruction. For simple branches (1-byte opcode + 1-byte displacement) the last operand is coded 'b?' where the "data type" '?' is a clue that we @@ -791,14 +795,14 @@ static const short int vax_operand_width_size[256] = and branch around a jump. This is by far the most common case. That is why the VIT_OPCODE_SYNTHETIC bit is set: it says this is a 0-byte op-code followed by 2 or more bytes of operand address. - + If the op-code has VIT_OPCODE_SPECIAL set, then we have a more unusual case. - + For JBSB & JBR the treatment is the similar, except (1) we have a 'bw' option before (2) we can directly JSB/JMP because there is no condition. These operands have 'b-' as their access/data type. - + That leaves a bunch of random opcodes: JACBx, JxOBxxx. In these cases, we do the same idea. JACBxxx are all marked with a 'b!' JAOBxxx & JSOBxxx are marked with a 'b:'. */ @@ -973,14 +977,14 @@ vip_begin (int synthetic_too, /* 1 means include jXXX op-codes. */ /* Take 3 char.s, the last of which may be `\0` (non-existent) and return the VAX register number that they represent. - + Return -1 if they don't form a register name. Good names return a number from 0:15 inclusive. - + Case is not important in a name. - + Register names understood are: - + R0 R1 R2 @@ -1077,20 +1081,20 @@ vax_reg_parse (char c1, char c2, char c3, char c4) For speed, expect a string of whitespace to be reduced to a single ' '. This is the case for GNU AS, and is easy for other DEC-compatible assemblers. - + Knowledge about DEC VAX assembler operand notation lives here. This doesn't even know what a register name is, except it believes all register names are 2 or 3 characters, and lets vax_reg_parse() say what number each name represents. It does, however, know that PC, SP etc are special registers so it can detect addressing modes that are silly for those registers. - + Where possible, it delivers 1 fatal or 1 warning message if the operand is suspect. Exactly what we test for is still evolving. --- Arg block. - + There were a number of 'mismatched argument type' bugs to vip_op. The most general solution is to typedef each (of many) arguments. We used instead a typedef'd argument block. This is less modular @@ -1098,7 +1102,7 @@ vax_reg_parse (char c1, char c2, char c3, char c4) on most engines, and seems to keep programmers happy. It will have to be done properly if we ever want to use vip_op as a general-purpose module (it was designed to be). - + G^ Doesn't support DEC "G^" format operands. These always take 5 bytes @@ -1109,14 +1113,14 @@ vax_reg_parse (char c1, char c2, char c3, char c4) If there is some other use for "G^", feel free to code it in! speed - + If I nested if()s more, I could avoid testing (*err) which would save time, space and page faults. I didn't nest all those if()s for clarity and because I think the mode testing can be re-arranged 1st to test the - commoner constructs 1st. Does anybody have statistics on this? - + commoner constructs 1st. Does anybody have statistics on this? + error messages - + In future, we should be able to 'compose' error messages in a scratch area and give the user MUCH more informative error messages. Although this takes a little more code at run-time, it will make this module much more self- @@ -1125,18 +1129,18 @@ vax_reg_parse (char c1, char c2, char c3, char c4) the Un*x characters "$`*", that most users will expect from this AS. ---- - + The input is a string, ending with '\0'. - + We also require a 'hint' of what kind of operand is expected: so we can remind caller not to write into literals for instance. - + The output is a skeletal instruction. - + The algorithm has two parts. 1. extract the syntactic features (parse off all the @^#-()+[] mode crud); 2. express the @^#-()+[] as some parameters suited to further analysis. - + 2nd step is where we detect the googles of possible invalid combinations a human (or compiler) might write. Note that if we do a half-way decent assembler, we don't know how long to make (eg) displacement @@ -1153,19 +1157,19 @@ vax_reg_parse (char c1, char c2, char c3, char c4) - error text(s) why we couldn't understand the operand ---- - + To decode output of this, test errtxt. If errtxt[0] == '\0', then we had no errors that prevented parsing. Also, if we ever report an internal bug, errtxt[0] is set non-zero. So one test tells you if the other outputs are to be taken seriously. ---- - + Dec defines the semantics of address modes (and values) by a two-letter code, explained here. - + letter 1: access type - + a address calculation - no data access, registers forbidden b branch displacement m read - let go of bus - write back "modify" @@ -1173,9 +1177,9 @@ vax_reg_parse (char c1, char c2, char c3, char c4) v bit field address: like 'a' but registers are OK w write space no operator (eg ".long foo") [our convention] - + letter 2: data type (i.e. width, alignment) - + b byte d double precision floating point (D format) f single precision floating point (F format) @@ -1188,11 +1192,11 @@ vax_reg_parse (char c1, char c2, char c3, char c4) ? simple synthetic branch operand - unconditional synthetic JSB/JSR operand ! complex synthetic branch operand - + The '-?!' letter 2's are not for external consumption. They are used for various assemblers. Generally, all unknown widths are assumed 0. We don't limit your choice of width character. - + DEC operands are hard work to parse. For example, '@' as the first character means indirect (deferred) mode but elsewhere it is a shift operator. @@ -1201,9 +1205,9 @@ vax_reg_parse (char c1, char c2, char c3, char c4) We try hard not to parse anything that MIGHT be part of the expression buried in that syntax. For example if we see @...(Rn) we don't check for '-' before the '(' because mode @-(Rn) does not exist. - + After parsing we have: - + at 1 if leading '@' (or Un*x '*') len takes one value from " bilsw". eg B^ -> 'b'. hash 1 if leading '#' (or Un*x '$') @@ -1214,7 +1218,7 @@ vax_reg_parse (char c1, char c2, char c3, char c4) paren 1 if () are around register reg major register number 0:15 -1 means absent ndx index register number 0:15 -1 means absent - + Again, I dare not explain it: just trace ALL the code! Summary of vip_op outputs. @@ -1271,10 +1275,8 @@ vip_op (char *optext, struct vop *vopP) get the types wrong below, we lose at compile time rather than at lint or run time. */ char access_mode; /* vop_access. */ - char width; /* vop_width. */ access_mode = vopP->vop_access; - width = vopP->vop_width; /* None of our code bugs (yet), no user text errors, no warnings even. */ err = wrn = 0; @@ -1314,7 +1316,7 @@ vip_op (char *optext, struct vop *vopP) /* p points to what may be the beginning of an expression. We have peeled off the front all that is peelable. We know at, len, hash. - + Lets point q at the end of the text and parse that (backwards). */ for (q = p; *q; q++) @@ -1489,7 +1491,7 @@ vip_op (char *optext, struct vop *vopP) We will deliver a 4-bit reg, and a 4-bit mode. */ /* Case of branch operand. Different. No L^B^W^I^S^ allowed for instance. - + in: at ? len ? hash ? @@ -1498,7 +1500,7 @@ vip_op (char *optext, struct vop *vopP) paren ? reg ? ndx ? - + out: mode 0 reg -1 len ' ' @@ -1517,7 +1519,7 @@ vip_op (char *optext, struct vop *vopP) /* Since nobody seems to use it: comment this 'feature'(?) out for now. */ #ifdef NEVER /* Case of stand-alone operand. e.g. ".long foo" - + in: at ? len ? hash ? @@ -1526,7 +1528,7 @@ vip_op (char *optext, struct vop *vopP) paren ? reg ? ndx ? - + out: mode 0 reg -1 len ' ' @@ -1563,7 +1565,7 @@ vip_op (char *optext, struct vop *vopP) #endif /* Case of S^#. - + in: at 0 len 's' definition hash 1 demand @@ -1572,7 +1574,7 @@ vip_op (char *optext, struct vop *vopP) paren 0 by "()" scan logic because "S^" seen reg -1 or nn by mistake ndx -1 - + out: mode 0 reg -1 len 's' @@ -1604,9 +1606,9 @@ vip_op (char *optext, struct vop *vopP) err = _("S^# may only read-access"); } } - + /* Case of -(Rn), which is weird case. - + in: at 0 len ' hash 0 @@ -1615,7 +1617,7 @@ vip_op (char *optext, struct vop *vopP) paren 1 by definition reg present by definition ndx optional - + out: mode 7 reg present len ' ' @@ -1646,7 +1648,7 @@ vip_op (char *optext, struct vop *vopP) } /* Case of (Rn)+, which is slightly different. - + in: at len ' ' hash 0 @@ -1655,7 +1657,7 @@ vip_op (char *optext, struct vop *vopP) paren 1 by definition reg present by definition ndx optional - + out: mode 8+@ reg present len ' ' @@ -1677,7 +1679,7 @@ vip_op (char *optext, struct vop *vopP) } /* Case of #, without S^. - + in: at len ' ' or 'i' hash 1 by definition @@ -1686,7 +1688,7 @@ vip_op (char *optext, struct vop *vopP) paren 0 reg absent ndx optional - + out: mode 8+@ reg PC len ' ' or 'i' @@ -1725,7 +1727,7 @@ vip_op (char *optext, struct vop *vopP) /* Case of Rn. We separate this one because it has a few special errors the remaining modes lack. - + in: at optional len ' ' hash 0 by program logic @@ -1734,7 +1736,7 @@ vip_op (char *optext, struct vop *vopP) paren 0 by definition reg present by definition ndx optional - + out: mode 5+@ reg present len ' ' enforce no length @@ -1771,7 +1773,7 @@ vip_op (char *optext, struct vop *vopP) paren == 1 OR reg==-1 */ /* Rest of cases fit into one bunch. - + in: at optional len ' ' or 'b' or 'w' or 'l' hash 0 by program logic @@ -1780,7 +1782,7 @@ vip_op (char *optext, struct vop *vopP) paren optional reg optional ndx optional - + out: mode 10 + @ + len reg optional len ' ' or 'b' or 'w' or 'l' @@ -1794,8 +1796,10 @@ vip_op (char *optext, struct vop *vopP) { case 'l': mode += 2; + /* Fall through. */ case 'w': mode += 2; + /* Fall through. */ case ' ': /* Assumed B^ until our caller changes it. */ case 'b': break; @@ -1830,15 +1834,15 @@ vip_op (char *optext, struct vop *vopP) knowledge of how you parse (or evaluate) your expressions. We do however strip off and decode addressing modes and operation mnemonic. - + The exploded instruction is returned to a struct vit of your choice. #include "vax-inst.h" to know what a struct vit is. - + This function's value is a string. If it is not "" then an internal logic error was found: read this code to assign meaning to the string. No argument string should generate such an error string: it means a bug in our code, not in the user's text. - + You MUST have called vip_begin() once before using this function. */ static void @@ -1863,7 +1867,7 @@ vip (struct vit *vitP, /* We build an exploded instruction here. */ if (*instring == ' ') ++instring; - + /* MUST end in end-of-string or exactly 1 space. */ for (p = instring; *p && *p != ' '; p++) ; @@ -2109,7 +2113,7 @@ main (void) default: my_operand_length = 2; - printf ("I dn't understand access width %c\n", mywidth); + printf ("I don't understand access width %c\n", mywidth); break; } printf ("VAX assembler instruction operand: "); @@ -2208,7 +2212,7 @@ struct option md_longopts[] = size_t md_longopts_size = sizeof (md_longopts); int -md_parse_option (int c, char *arg) +md_parse_option (int c, const char *arg) { switch (c) { @@ -2340,7 +2344,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) if (fixp->fx_tcbit) abort (); - if (fixp->fx_r_type != BFD_RELOC_NONE) + if (fixp->fx_r_type != NO_RELOC) { code = fixp->fx_r_type; @@ -2386,8 +2390,8 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) #undef F #undef MAP - reloc = xmalloc (sizeof (arelent)); - reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); + reloc = XNEW (arelent); + reloc->sym_ptr_ptr = XNEW (asymbol *); *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; #ifndef OBJ_ELF @@ -2713,6 +2717,7 @@ md_assemble (char *instruction_string) if (need_pass_2 || goofed) return; + dwarf2_emit_insn (0); /* Emit op-code. */ /* Remember where it is, in case we want to modify the op-code later. */ opcode_low_byteP = frag_more (v.vit_opcode_nbytes); @@ -3124,9 +3129,9 @@ md_assemble (char *instruction_string) || operandP->vop_access == 'a') { if (operandP->vop_access == 'v') - as_warn (_("Invalid operand: immediate value used as base address.")); + as_warn (_("Invalid operand: immediate value used as base address.")); else - as_warn (_("Invalid operand: immediate value used as address.")); + as_warn (_("Invalid operand: immediate value used as address.")); /* gcc 2.6.3 is known to generate these in at least one case. */ } @@ -3267,12 +3272,11 @@ md_begin (void) } } -static char *vax_cons_special_reloc; - -void +bfd_reloc_code_real_type vax_cons (expressionS *exp, int size) { char *save; + const char *vax_cons_special_reloc; SKIP_WHITESPACE (); vax_cons_special_reloc = NULL; @@ -3376,38 +3380,32 @@ vax_cons (expressionS *exp, int size) } if (vax_cons_special_reloc == NULL) expression (exp); + else + switch (size) + { + case 1: return BFD_RELOC_8_PCREL; + case 2: return BFD_RELOC_16_PCREL; + case 4: return BFD_RELOC_32_PCREL; + } + return NO_RELOC; } /* This is called by emit_expr via TC_CONS_FIX_NEW when creating a reloc for a cons. */ void -vax_cons_fix_new (fragS *frag, int where, unsigned int nbytes, expressionS *exp) +vax_cons_fix_new (fragS *frag, int where, unsigned int nbytes, expressionS *exp, + bfd_reloc_code_real_type r) { - bfd_reloc_code_real_type r; - - r = (nbytes == 1 ? BFD_RELOC_8 : - (nbytes == 2 ? BFD_RELOC_16 : BFD_RELOC_32)); - - if (vax_cons_special_reloc) - { - if (*vax_cons_special_reloc == 'p') - { - switch (nbytes) - { - case 1: r = BFD_RELOC_8_PCREL; break; - case 2: r = BFD_RELOC_16_PCREL; break; - case 4: r = BFD_RELOC_32_PCREL; break; - default: abort (); - } - } - } + if (r == NO_RELOC) + r = (nbytes == 1 ? BFD_RELOC_8 + : nbytes == 2 ? BFD_RELOC_16 + : BFD_RELOC_32); fix_new_exp (frag, where, (int) nbytes, exp, 0, r); - vax_cons_special_reloc = NULL; } -char * +const char * md_atof (int type, char * litP, int * sizeP) { return vax_md_atof (type, litP, sizeP);