Changeset 609 for branches/GNU/src/binutils/gas/cgen.c
- Timestamp:
- Aug 16, 2003, 6:59:22 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GNU/src/binutils/gas/cgen.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.1.1.2
r608 r609 1 1 /* GAS interface for targets using CGEN: Cpu tools GENerator. 2 Copyright 1996, 1997, 1998, 1999, 2000, 2001 2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 3 3 Free Software Foundation, Inc. 4 4 5 This file is part of GAS, the GNU Assembler.6 7 GAS is free software; you can redistribute it and/or modify8 it under the terms of the GNU General Public License as published by9 the Free Software Foundation; either version 2, or (at your option)10 any later version.11 12 GAS is distributed in the hope that it will be useful,13 but WITHOUT ANY WARRANTY; without even the implied warranty of14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15 GNU General Public License for more details.16 17 You should have received a copy of the GNU General Public License18 along with GAS; see the file COPYING. If not, write to the Free Software19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */5 This file is part of GAS, the GNU Assembler. 6 7 GAS is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2, or (at your option) 10 any later version. 11 12 GAS is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GAS; see the file COPYING. If not, write to the Free Software 19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 20 20 21 21 #include <setjmp.h> … … 30 30 #include "dwarf2dbg.h" 31 31 32 static void queue_fixup PARAMS ((int, int, expressionS *)); 33 32 34 /* Opcode table descriptor, must be set by md_begin. */ 33 35 … … 60 62 OPINFO is something the caller chooses to help in reloc determination. */ 61 63 62 struct fixup { 64 struct fixup 65 { 63 66 int opindex; 64 67 int opinfo; … … 95 98 } 96 99 97 /* The following three functions allow a backup of the fixup chain to be made, 98 and to have this backup be swapped with the current chain. This allows 99 certain ports, eg the m32r, to swap two instructions and swap their fixups 100 at the same time. */ 101 /* ??? I think with cgen_asm_finish_insn (or something else) there is no 102 more need for this. */ 103 104 static struct fixup saved_fixups[GAS_CGEN_MAX_FIXUPS]; 105 static int saved_num_fixups; 106 107 void 108 gas_cgen_save_fixups () 109 { 110 saved_num_fixups = num_fixups; 111 112 memcpy (saved_fixups, fixups, sizeof (fixups[0]) * num_fixups); 113 100 /* The following functions allow fixup chains to be stored, retrieved, 101 and swapped. They are a generalization of a pre-existing scheme 102 for storing, restoring and swapping fixup chains that was used by 103 the m32r port. The functionality is essentially the same, only 104 instead of only being able to store a single fixup chain, an entire 105 array of fixup chains can be stored. It is the user's responsibility 106 to keep track of how many fixup chains have been stored and which 107 elements of the array they are in. 108 109 The algorithms used are the same as in the old scheme. Other than the 110 "array-ness" of the whole thing, the functionality is identical to the 111 old scheme. 112 113 gas_cgen_initialize_saved_fixups_array(): 114 Sets num_fixups_in_chain to 0 for each element. Call this from 115 md_begin() if you plan to use these functions and you want the 116 fixup count in each element to be set to 0 initially. This is 117 not necessary, but it's included just in case. It performs 118 the same function for each element in the array of fixup chains 119 that gas_init_parse() performs for the current fixups. 120 121 gas_cgen_save_fixups (element): 122 element - element number of the array you wish to store the fixups 123 to. No mechanism is built in for tracking what element 124 was last stored to. 125 126 gas_cgen_restore_fixups (element): 127 element - element number of the array you wish to restore the fixups 128 from. 129 130 gas_cgen_swap_fixups(int element): 131 element - swap the current fixups with those in this element number. 132 */ 133 134 struct saved_fixups 135 { 136 struct fixup fixup_chain[GAS_CGEN_MAX_FIXUPS]; 137 int num_fixups_in_chain; 138 }; 139 140 static struct saved_fixups stored_fixups[MAX_SAVED_FIXUP_CHAINS]; 141 142 void 143 gas_cgen_initialize_saved_fixups_array () 144 { 145 int i = 0; 146 147 while (i < MAX_SAVED_FIXUP_CHAINS) 148 stored_fixups[i++].num_fixups_in_chain = 0; 149 } 150 151 void 152 gas_cgen_save_fixups (i) 153 int i; 154 { 155 if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS) 156 { 157 as_fatal ("index into stored_fixups[] out of bounds"); 158 return; 159 } 160 161 stored_fixups[i].num_fixups_in_chain = num_fixups; 162 memcpy (stored_fixups[i].fixup_chain, fixups, 163 sizeof (fixups[0]) * num_fixups); 114 164 num_fixups = 0; 115 165 } 116 166 117 167 void 118 gas_cgen_restore_fixups () 119 { 120 num_fixups = saved_num_fixups; 121 122 memcpy (fixups, saved_fixups, sizeof (fixups[0]) * num_fixups); 123 124 saved_num_fixups = 0; 125 } 126 127 void 128 gas_cgen_swap_fixups () 129 { 130 int tmp; 131 struct fixup tmp_fixup; 168 gas_cgen_restore_fixups (i) 169 int i; 170 { 171 if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS) 172 { 173 as_fatal ("index into stored_fixups[] out of bounds"); 174 return; 175 } 176 177 num_fixups = stored_fixups[i].num_fixups_in_chain; 178 memcpy (fixups, stored_fixups[i].fixup_chain, 179 (sizeof (stored_fixups[i].fixup_chain[0])) * num_fixups); 180 stored_fixups[i].num_fixups_in_chain = 0; 181 } 182 183 void 184 gas_cgen_swap_fixups (i) 185 int i; 186 { 187 if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS) 188 { 189 as_fatal ("index into stored_fixups[] out of bounds"); 190 return; 191 } 132 192 133 193 if (num_fixups == 0) 134 { 135 gas_cgen_restore_fixups (); 136 } 137 else if (saved_num_fixups == 0) 138 { 139 gas_cgen_save_fixups (); 140 } 194 gas_cgen_restore_fixups (i); 195 196 else if (stored_fixups[i].num_fixups_in_chain == 0) 197 gas_cgen_save_fixups (i); 198 141 199 else 142 200 { 143 tmp = saved_num_fixups; 144 saved_num_fixups = num_fixups; 201 int tmp; 202 struct fixup tmp_fixup; 203 204 tmp = stored_fixups[i].num_fixups_in_chain; 205 stored_fixups[i].num_fixups_in_chain = num_fixups; 145 206 num_fixups = tmp; 146 207 147 208 for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;) 148 209 { 149 tmp_fixup = saved_fixups[tmp];150 s aved_fixups[tmp] = fixups [tmp];151 fixups [tmp] 210 tmp_fixup = stored_fixups[i].fixup_chain [tmp]; 211 stored_fixups[i].fixup_chain[tmp] = fixups [tmp]; 212 fixups [tmp] = tmp_fixup; 152 213 } 153 214 } … … 165 226 operands residing in the insn, but instead just use the 166 227 operand index. This lets us easily handle fixups for any 167 operand type. We pick a BFD reloc type in md_apply_fix . */228 operand type. We pick a BFD reloc type in md_apply_fix3. */ 168 229 169 230 fixS * … … 182 243 /* It may seem strange to use operand->attrs and not insn->attrs here, 183 244 but it is the operand that has a pc relative relocation. */ 184 185 245 fixP = fix_new (frag, where, length / 8, symbol, offset, 186 246 CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR), … … 205 265 operands residing in the insn, but instead just use the 206 266 operand index. This lets us easily handle fixups for any 207 operand type. We pick a BFD reloc type in md_apply_fix . */267 operand type. We pick a BFD reloc type in md_apply_fix3. */ 208 268 209 269 fixS * … … 221 281 /* It may seem strange to use operand->attrs and not insn->attrs here, 222 282 but it is the operand that has a pc relative relocation. */ 223 224 283 fixP = fix_new_exp (frag, where, length / 8, exp, 225 284 CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR), … … 266 325 static enum cgen_parse_operand_result *resultP_1; 267 326 #endif 268 const char *errmsg = NULL;327 const char *errmsg; 269 328 expressionS exp; 270 329 … … 286 345 input_line_pointer = (char *) hold; 287 346 *resultP_1 = CGEN_PARSE_OPERAND_RESULT_ERROR; 288 return "illegal operand";347 return _("illegal operand"); 289 348 } 290 349 … … 292 351 expression (&exp); 293 352 expr_jmp_buf_p = 0; 353 errmsg = NULL; 294 354 295 355 *strP = input_line_pointer; … … 510 570 should handle them all. */ 511 571 512 int 513 gas_cgen_md_apply_fix3 (fixP, val ueP, seg)572 void 573 gas_cgen_md_apply_fix3 (fixP, valP, seg) 514 574 fixS * fixP; 515 valueT * val ueP;575 valueT * valP; 516 576 segT seg ATTRIBUTE_UNUSED; 517 577 { 518 578 char *where = fixP->fx_frag->fr_literal + fixP->fx_where; 519 valueT value ;579 valueT value = * valP; 520 580 /* Canonical name, since used a lot. */ 521 581 CGEN_CPU_DESC cd = gas_cgen_cpu_desc; 522 582 523 /* FIXME FIXME FIXME: The value we are passed in *valuep includes524 the symbol values. Since we are using BFD_ASSEMBLER, if we are525 doing this relocation the code in write.c is going to call526 bfd_install_relocation, which is also going to use the symbol527 value. That means that if the reloc is fully resolved we want to528 use *valuep since bfd_install_relocation is not being used.529 However, if the reloc is not fully resolved we do not want to use530 *valuep, and must use fx_offset instead. However, if the reloc531 is PC relative, we do want to use *valuep since it includes the532 result of md_pcrel_from. This is confusing. */533 534 583 if (fixP->fx_addsy == (symbolS *) NULL) 535 { 536 value = *valueP; 537 fixP->fx_done = 1; 538 } 539 else if (fixP->fx_pcrel) 540 value = *valueP; 541 else 542 { 543 value = fixP->fx_offset; 544 if (fixP->fx_subsy != (symbolS *) NULL) 545 { 546 if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section) 547 value -= S_GET_VALUE (fixP->fx_subsy); 548 else 549 { 550 /* We don't actually support subtracting a symbol. */ 551 as_bad_where (fixP->fx_file, fixP->fx_line, 552 _("expression too complex")); 553 } 554 } 555 } 584 fixP->fx_done = 1; 585 586 /* We don't actually support subtracting a symbol. */ 587 if (fixP->fx_subsy != (symbolS *) NULL) 588 as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex")); 556 589 557 590 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED) … … 595 628 596 629 if (fixP->fx_done) 597 return 1;630 return; 598 631 599 632 /* The operand isn't fully resolved. Determine a BFD reloc value … … 603 636 604 637 reloc_type = md_cgen_lookup_reloc (insn, operand, fixP); 638 605 639 if (reloc_type != BFD_RELOC_NONE) 606 { 607 fixP->fx_r_type = reloc_type; 608 } 640 fixP->fx_r_type = reloc_type; 609 641 else 610 642 { … … 612 644 _("unresolved expression that must be resolved")); 613 645 fixP->fx_done = 1; 614 return 1;646 return; 615 647 } 616 648 } … … 640 672 } 641 673 } 642 else 643 { 644 /* bfd_install_relocation will be called to finish things up. */ 645 } 674 /* else 675 bfd_install_relocation will be called to finish things up. */ 646 676 647 677 /* Tuck `value' away for use by tc_gen_reloc. … … 649 679 This field is misnamed (or misused :-). */ 650 680 fixP->fx_addnumber = value; 651 652 return 1;653 681 } 654 682 … … 689 717 return reloc; 690 718 } 719 720 /* Perform any cgen specific initialisation. 721 Called after gas_cgen_cpu_desc has been created. */ 722 723 void 724 gas_cgen_begin () 725 { 726 if (flag_signed_overflow_ok) 727 cgen_set_signed_overflow_ok (gas_cgen_cpu_desc); 728 else 729 cgen_clear_signed_overflow_ok (gas_cgen_cpu_desc); 730 } -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.