1 /* GAS interface for targets using CGEN: Cpu tools GENerator.
2 Copyright (C) 1996-2015 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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)
11 GAS is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
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 the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
23 #include "cgen-desc.h"
26 #include "dwarf2dbg.h"
29 #include "struc-symbol.h"
31 #ifdef OBJ_COMPLEX_RELC
32 static expressionS * make_right_shifted_expr
33 (expressionS *, const int, const int);
35 static unsigned long gas_cgen_encode_addend
36 (const unsigned long, const unsigned long, const unsigned long, \
37 const unsigned long, const unsigned long, const unsigned long, \
40 static char * weak_operand_overflow_check
41 (const expressionS *, const CGEN_OPERAND *);
43 static void queue_fixup_recursively
44 (const int, const int, expressionS *, \
45 const CGEN_MAYBE_MULTI_IFLD *, const int, const int);
47 static int rightshift = 0;
49 static void queue_fixup (int, int, expressionS *);
51 /* Opcode table descriptor, must be set by md_begin. */
53 CGEN_CPU_DESC gas_cgen_cpu_desc;
55 /* Callback to insert a register into the symbol table.
56 A target may choose to let GAS parse the registers.
57 ??? Not currently used. */
60 cgen_asm_record_register (name, number)
64 /* Use symbol_create here instead of symbol_new so we don't try to
65 output registers into the object file's symbol table. */
66 symbol_table_insert (symbol_create (name, reg_section,
67 number, &zero_address_frag));
70 /* We need to keep a list of fixups. We can't simply generate them as
71 we go, because that would require us to first create the frag, and
72 that would screw up references to ``.''.
74 This is used by cpu's with simple operands. It keeps knowledge of what
75 an `expressionS' is and what a `fixup' is out of CGEN which for the time
78 OPINDEX is the index in the operand table.
79 OPINFO is something the caller chooses to help in reloc determination. */
86 struct cgen_maybe_multi_ifield * field;
90 static struct fixup fixups[GAS_CGEN_MAX_FIXUPS];
91 static int num_fixups;
93 /* Prepare to parse an instruction.
94 ??? May wish to make this static and delete calls in md_assemble. */
97 gas_cgen_init_parse ()
105 queue_fixup (opindex, opinfo, expP)
110 /* We need to generate a fixup for this expression. */
111 if (num_fixups >= GAS_CGEN_MAX_FIXUPS)
112 as_fatal (_("too many fixups"));
113 fixups[num_fixups].exp = *expP;
114 fixups[num_fixups].opindex = opindex;
115 fixups[num_fixups].opinfo = opinfo;
119 /* The following functions allow fixup chains to be stored, retrieved,
120 and swapped. They are a generalization of a pre-existing scheme
121 for storing, restoring and swapping fixup chains that was used by
122 the m32r port. The functionality is essentially the same, only
123 instead of only being able to store a single fixup chain, an entire
124 array of fixup chains can be stored. It is the user's responsibility
125 to keep track of how many fixup chains have been stored and which
126 elements of the array they are in.
128 The algorithms used are the same as in the old scheme. Other than the
129 "array-ness" of the whole thing, the functionality is identical to the
132 gas_cgen_initialize_saved_fixups_array():
133 Sets num_fixups_in_chain to 0 for each element. Call this from
134 md_begin() if you plan to use these functions and you want the
135 fixup count in each element to be set to 0 initially. This is
136 not necessary, but it's included just in case. It performs
137 the same function for each element in the array of fixup chains
138 that gas_init_parse() performs for the current fixups.
140 gas_cgen_save_fixups (element):
141 element - element number of the array you wish to store the fixups
142 to. No mechanism is built in for tracking what element
145 gas_cgen_restore_fixups (element):
146 element - element number of the array you wish to restore the fixups
149 gas_cgen_swap_fixups(int element):
150 element - swap the current fixups with those in this element number.
155 struct fixup fixup_chain[GAS_CGEN_MAX_FIXUPS];
156 int num_fixups_in_chain;
159 static struct saved_fixups stored_fixups[MAX_SAVED_FIXUP_CHAINS];
162 gas_cgen_initialize_saved_fixups_array ()
166 while (i < MAX_SAVED_FIXUP_CHAINS)
167 stored_fixups[i++].num_fixups_in_chain = 0;
171 gas_cgen_save_fixups (i)
174 if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
176 as_fatal ("index into stored_fixups[] out of bounds");
180 stored_fixups[i].num_fixups_in_chain = num_fixups;
181 memcpy (stored_fixups[i].fixup_chain, fixups,
182 sizeof (fixups[0]) * num_fixups);
187 gas_cgen_restore_fixups (i)
190 if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
192 as_fatal ("index into stored_fixups[] out of bounds");
196 num_fixups = stored_fixups[i].num_fixups_in_chain;
197 memcpy (fixups, stored_fixups[i].fixup_chain,
198 (sizeof (stored_fixups[i].fixup_chain[0])) * num_fixups);
199 stored_fixups[i].num_fixups_in_chain = 0;
203 gas_cgen_swap_fixups (i)
206 if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
208 as_fatal ("index into stored_fixups[] out of bounds");
213 gas_cgen_restore_fixups (i);
215 else if (stored_fixups[i].num_fixups_in_chain == 0)
216 gas_cgen_save_fixups (i);
221 struct fixup tmp_fixup;
223 tmp = stored_fixups[i].num_fixups_in_chain;
224 stored_fixups[i].num_fixups_in_chain = num_fixups;
227 for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;)
229 tmp_fixup = stored_fixups[i].fixup_chain [tmp];
230 stored_fixups[i].fixup_chain[tmp] = fixups [tmp];
231 fixups [tmp] = tmp_fixup;
236 /* Default routine to record a fixup.
237 This is a cover function to fix_new.
238 It exists because we record INSN with the fixup.
240 FRAG and WHERE are their respective arguments to fix_new_exp.
242 OPINFO is something the caller chooses to help in reloc determination.
244 At this point we do not use a bfd_reloc_code_real_type for
245 operands residing in the insn, but instead just use the
246 operand index. This lets us easily handle fixups for any
247 operand type. We pick a BFD reloc type in md_apply_fix. */
250 gas_cgen_record_fixup (frag, where, insn, length, operand, opinfo, symbol, offset)
253 const CGEN_INSN * insn;
255 const CGEN_OPERAND * operand;
262 /* It may seem strange to use operand->attrs and not insn->attrs here,
263 but it is the operand that has a pc relative relocation. */
264 fixP = fix_new (frag, where, length / 8, symbol, offset,
265 CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
266 (bfd_reloc_code_real_type)
267 ((int) BFD_RELOC_UNUSED
268 + (int) operand->type));
269 fixP->fx_cgen.insn = insn;
270 fixP->fx_cgen.opinfo = opinfo;
271 fixP->fx_cgen.field = NULL;
272 fixP->fx_cgen.msb_field_p = 0;
277 /* Default routine to record a fixup given an expression.
278 This is a cover function to fix_new_exp.
279 It exists because we record INSN with the fixup.
281 FRAG and WHERE are their respective arguments to fix_new_exp.
283 OPINFO is something the caller chooses to help in reloc determination.
285 At this point we do not use a bfd_reloc_code_real_type for
286 operands residing in the insn, but instead just use the
287 operand index. This lets us easily handle fixups for any
288 operand type. We pick a BFD reloc type in md_apply_fix. */
291 gas_cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp)
294 const CGEN_INSN * insn;
296 const CGEN_OPERAND * operand;
302 /* It may seem strange to use operand->attrs and not insn->attrs here,
303 but it is the operand that has a pc relative relocation. */
304 fixP = fix_new_exp (frag, where, length / 8, exp,
305 CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
306 (bfd_reloc_code_real_type)
307 ((int) BFD_RELOC_UNUSED
308 + (int) operand->type));
309 fixP->fx_cgen.insn = insn;
310 fixP->fx_cgen.opinfo = opinfo;
311 fixP->fx_cgen.field = NULL;
312 fixP->fx_cgen.msb_field_p = 0;
317 #ifdef OBJ_COMPLEX_RELC
319 expr_build_binary (operatorT op, symbolS * s1, symbolS * s2)
327 return make_expr_symbol (& e);
331 /* Used for communication between the next two procedures. */
332 static jmp_buf expr_jmp_buf;
333 static int expr_jmp_buf_p;
335 /* Callback for cgen interface. Parse the expression at *STRP.
336 The result is an error message or NULL for success (in which case
337 *STRP is advanced past the parsed text).
338 WANT is an indication of what the caller is looking for.
339 If WANT == CGEN_ASM_PARSE_INIT the caller is beginning to try to match
340 a table entry with the insn, reset the queued fixups counter.
341 An enum cgen_parse_operand_result is stored in RESULTP.
342 OPINDEX is the operand's table entry index.
343 OPINFO is something the caller chooses to help in reloc determination.
344 The resulting value is stored in VALUEP. */
347 gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
349 #ifdef OBJ_COMPLEX_RELC
352 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
354 enum cgen_parse_operand_type want;
358 enum cgen_parse_operand_result *resultP;
362 /* These are volatile to survive the setjmp. */
363 char * volatile hold;
364 enum cgen_parse_operand_result * volatile resultP_1;
365 volatile int opinfo_1;
368 static enum cgen_parse_operand_result *resultP_1;
374 #ifdef OBJ_COMPLEX_RELC
375 volatile int signed_p = 0;
376 symbolS * stmp = NULL;
377 bfd_reloc_code_real_type reloc_type;
378 const CGEN_OPERAND * operand;
381 if (want == CGEN_PARSE_OPERAND_INIT)
383 gas_cgen_init_parse ();
388 hold = input_line_pointer;
389 input_line_pointer = (char *) *strP;
392 /* We rely on md_operand to longjmp back to us.
393 This is done via gas_cgen_md_operand. */
394 if (setjmp (expr_jmp_buf) != 0)
397 input_line_pointer = (char *) hold;
398 *resultP_1 = CGEN_PARSE_OPERAND_RESULT_ERROR;
399 return _("illegal operand");
407 *strP = input_line_pointer;
408 input_line_pointer = hold;
410 #ifdef TC_CGEN_PARSE_FIX_EXP
411 opinfo_1 = TC_CGEN_PARSE_FIX_EXP (opinfo_1, & exp);
414 /* FIXME: Need to check `want'. */
419 errmsg = _("illegal operand");
420 *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
423 errmsg = _("missing operand");
424 *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
427 if (want == CGEN_PARSE_OPERAND_SYMBOLIC)
429 *valueP = exp.X_add_number;
430 *resultP = CGEN_PARSE_OPERAND_RESULT_NUMBER;
433 *valueP = exp.X_add_number;
434 *resultP = CGEN_PARSE_OPERAND_RESULT_REGISTER;
438 #ifdef OBJ_COMPLEX_RELC
439 /* Look up operand, check to see if there's an obvious
440 overflow (this helps disambiguate some insn parses). */
441 operand = cgen_operand_lookup_by_num (cd, opindex);
442 errmsg = weak_operand_overflow_check (& exp, operand);
446 /* Fragment the expression as necessary, and queue a reloc. */
447 memset (& dummy_fixup, 0, sizeof (fixS));
449 reloc_type = md_cgen_lookup_reloc (0, operand, & dummy_fixup);
451 if (exp.X_op == O_symbol
452 && reloc_type == BFD_RELOC_RELC
453 && exp.X_add_symbol->sy_value.X_op == O_constant
454 && (!exp.X_add_symbol->bsym
455 || (exp.X_add_symbol->bsym->section != expr_section
456 && exp.X_add_symbol->bsym->section != absolute_section
457 && exp.X_add_symbol->bsym->section != undefined_section)))
459 /* Local labels will have been (eagerly) turned into constants
460 by now, due to the inappropriately deep insight of the
461 expression parser. Unfortunately make_expr_symbol
462 prematurely dives into the symbol evaluator, and in this
463 case it gets a bad answer, so we manually create the
464 expression symbol we want here. */
465 stmp = symbol_create (FAKE_LABEL_NAME, expr_section, 0,
466 & zero_address_frag);
467 symbol_set_value_expression (stmp, & exp);
470 stmp = make_expr_symbol (& exp);
472 /* If this is a pc-relative RELC operand, we
473 need to subtract "." from the expression. */
474 if (reloc_type == BFD_RELOC_RELC
475 && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR))
476 stmp = expr_build_binary (O_subtract, stmp, expr_build_dot ());
478 /* FIXME: this is not a perfect heuristic for figuring out
479 whether an operand is signed: it only works when the operand
480 is an immediate. it's not terribly likely that any other
481 values will be signed relocs, but it's possible. */
482 if (operand && (operand->hw_type == HW_H_SINT))
485 if (stmp->bsym && (stmp->bsym->section == expr_section)
486 && ! S_IS_LOCAL (stmp))
489 stmp->bsym->flags |= BSF_SRELC;
491 stmp->bsym->flags |= BSF_RELC;
494 /* Now package it all up for the fixup emitter. */
497 exp.X_add_symbol = stmp;
498 exp.X_add_number = 0;
500 /* Re-init rightshift quantity, just in case. */
501 rightshift = operand->length;
502 queue_fixup_recursively (opindex, opinfo_1, & exp,
503 (reloc_type == BFD_RELOC_RELC) ?
504 & (operand->index_fields) : 0,
508 ? CGEN_PARSE_OPERAND_RESULT_ERROR
509 : CGEN_PARSE_OPERAND_RESULT_QUEUED;
512 queue_fixup (opindex, opinfo_1, &exp);
514 *resultP = CGEN_PARSE_OPERAND_RESULT_QUEUED;
522 /* md_operand handler to catch unrecognized expressions and halt the
523 parsing process so the next entry can be tried.
525 ??? This could be done differently by adding code to `expression'. */
528 gas_cgen_md_operand (expressionP)
529 expressionS *expressionP ATTRIBUTE_UNUSED;
531 /* Don't longjmp if we're not called from within cgen_parse_operand(). */
533 longjmp (expr_jmp_buf, 1);
536 /* Finish assembling instruction INSN.
537 BUF contains what we've built up so far.
538 LENGTH is the size of the insn in bits.
539 RELAX_P is non-zero if relaxable insns should be emitted as such.
540 Otherwise they're emitted in non-relaxable forms.
541 The "result" is stored in RESULT if non-NULL. */
544 gas_cgen_finish_insn (insn, buf, length, relax_p, result)
545 const CGEN_INSN *insn;
546 CGEN_INSN_BYTES_PTR buf;
549 finished_insnS *result;
554 unsigned int byte_len = length / 8;
556 /* ??? Target foo issues various warnings here, so one might want to provide
557 a hook here. However, our caller is defined in tc-foo.c so there
558 shouldn't be a need for a hook. */
560 /* Write out the instruction.
561 It is important to fetch enough space in one call to `frag_more'.
562 We use (f - frag_now->fr_literal) to compute where we are and we
563 don't want frag_now to change between calls.
565 Relaxable instructions: We need to ensure we allocate enough
566 space for the largest insn. */
568 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED))
569 /* These currently shouldn't get here. */
572 /* Is there a relaxable insn with the relaxable operand needing a fixup? */
575 if (relax_p && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE))
577 /* Scan the fixups for the operand affected by relaxing
578 (i.e. the branch address). */
580 for (i = 0; i < num_fixups; ++i)
582 if (CGEN_OPERAND_ATTR_VALUE (cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex),
591 if (relax_operand != -1)
599 #ifdef TC_CGEN_MAX_RELAX
600 max_len = TC_CGEN_MAX_RELAX (insn, byte_len);
602 max_len = CGEN_MAX_INSN_SIZE;
604 /* Ensure variable part and fixed part are in same fragment. */
605 /* FIXME: Having to do this seems like a hack. */
608 /* Allocate space for the fixed part. */
609 f = frag_more (byte_len);
611 /* Create a relaxable fragment for this instruction. */
614 exp = &fixups[relax_operand].exp;
615 sym = exp->X_add_symbol;
616 off = exp->X_add_number;
617 if (exp->X_op != O_constant && exp->X_op != O_symbol)
619 /* Handle complex expressions. */
620 sym = make_expr_symbol (exp);
624 frag_var (rs_machine_dependent,
625 max_len - byte_len /* max chars */,
626 0 /* variable part already allocated */,
627 /* FIXME: When we machine generate the relax table,
628 machine generate a macro to compute subtype. */
634 /* Record the operand number with the fragment so md_convert_frag
635 can use gas_cgen_md_record_fixup to record the appropriate reloc. */
636 old_frag->fr_cgen.insn = insn;
637 old_frag->fr_cgen.opindex = fixups[relax_operand].opindex;
638 old_frag->fr_cgen.opinfo = fixups[relax_operand].opinfo;
640 result->frag = old_frag;
644 f = frag_more (byte_len);
646 result->frag = frag_now;
649 /* If we're recording insns as numbers (rather than a string of bytes),
650 target byte order handling is deferred until now. */
652 cgen_put_insn_value (gas_cgen_cpu_desc, (unsigned char *) f, length, *buf);
654 memcpy (f, buf, byte_len);
657 /* Emit DWARF2 debugging information. */
658 dwarf2_emit_insn (byte_len);
660 /* Create any fixups. */
661 for (i = 0; i < num_fixups; ++i)
664 const CGEN_OPERAND *operand =
665 cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex);
667 /* Don't create fixups for these. That's done during relaxation.
668 We don't need to test for CGEN_INSN_RELAXED as they can't get here
671 && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE)
672 && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_RELAX))
675 #ifndef md_cgen_record_fixup_exp
676 #define md_cgen_record_fixup_exp gas_cgen_record_fixup_exp
679 fixP = md_cgen_record_fixup_exp (frag_now, f - frag_now->fr_literal,
680 insn, length, operand,
683 fixP->fx_cgen.field = fixups[i].field;
684 fixP->fx_cgen.msb_field_p = fixups[i].msb_field_p;
686 result->fixups[i] = fixP;
691 result->num_fixups = num_fixups;
696 #ifdef OBJ_COMPLEX_RELC
697 /* Queue many fixups, recursively. If the field is a multi-ifield,
698 repeatedly queue its sub-parts, right shifted to fit into the field (we
699 assume here multi-fields represent a left-to-right, MSB0-LSB0
703 queue_fixup_recursively (const int opindex,
706 const CGEN_MAYBE_MULTI_IFLD * field,
708 const int part_of_multi)
710 if (field && field->count)
714 for (i = 0; i < field->count; ++ i)
715 queue_fixup_recursively (opindex, opinfo, expP,
716 & (field->val.multi[i]), signed_p, i);
720 expressionS * new_exp = expP;
723 printf ("queueing fixup for field %s\n",
724 (field ? field->val.leaf->name : "??"));
725 print_symbol_value (expP->X_add_symbol);
727 if (field && part_of_multi != -1)
729 rightshift -= field->val.leaf->length;
731 /* Shift reloc value by number of bits remaining after this
734 new_exp = make_right_shifted_expr (expP, rightshift, signed_p);
737 /* Truncate reloc values to length, *after* leftmost one. */
738 fixups[num_fixups].msb_field_p = (part_of_multi <= 0);
739 fixups[num_fixups].field = (CGEN_MAYBE_MULTI_IFLD *) field;
741 queue_fixup (opindex, opinfo, new_exp);
745 /* Encode the self-describing RELC reloc format's addend. */
748 gas_cgen_encode_addend (const unsigned long start, /* in bits */
749 const unsigned long len, /* in bits */
750 const unsigned long oplen, /* in bits */
751 const unsigned long wordsz, /* in bytes */
752 const unsigned long chunksz, /* in bytes */
753 const unsigned long signed_p,
754 const unsigned long trunc_p)
756 unsigned long res = 0L;
759 res |= (oplen & 0x3F) << 6;
760 res |= (len & 0x3F) << 12;
761 res |= (wordsz & 0xF) << 18;
762 res |= (chunksz & 0xF) << 22;
763 res |= (CGEN_INSN_LSB0_P ? 1 : 0) << 27;
764 res |= signed_p << 28;
765 res |= trunc_p << 29;
770 /* Purpose: make a weak check that the expression doesn't overflow the
771 operand it's to be inserted into.
773 Rationale: some insns used to use %operators to disambiguate during a
774 parse. when these %operators are translated to expressions by the macro
775 expander, the ambiguity returns. we attempt to disambiguate by field
778 Method: check to see if the expression's top node is an O_and operator,
779 and the mask is larger than the operand length. This would be an
780 overflow, so signal it by returning an error string. Any other case is
781 ambiguous, so we assume it's OK and return NULL. */
784 weak_operand_overflow_check (const expressionS * exp,
785 const CGEN_OPERAND * operand)
787 const unsigned long len = operand->length;
789 unsigned long opmask = (((1L << (len - 1)) - 1) << 1) | 1;
794 if (exp->X_op != O_bit_and)
796 /* Check for implicit overflow flag. */
797 if (CGEN_OPERAND_ATTR_VALUE
798 (operand, CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW))
799 return _("a reloc on this operand implies an overflow");
803 mask = exp->X_add_number;
805 if (exp->X_add_symbol
806 && exp->X_add_symbol->sy_value.X_op == O_constant)
807 mask |= exp->X_add_symbol->sy_value.X_add_number;
810 && exp->X_op_symbol->sy_value.X_op == O_constant)
811 mask |= exp->X_op_symbol->sy_value.X_add_number;
813 /* Want to know if mask covers more bits than opmask.
814 this is the same as asking if mask has any bits not in opmask,
815 or whether (mask & ~opmask) is nonzero. */
816 if (mask && (mask & ~opmask))
819 printf ("overflow: (mask = %8.8x, ~opmask = %8.8x, AND = %8.8x)\n",
820 mask, ~opmask, (mask & ~opmask));
822 return _("operand mask overflow");
829 make_right_shifted_expr (expressionS * exp,
834 expressionS * new_exp;
836 stmp = expr_build_binary (O_right_shift,
837 make_expr_symbol (exp),
838 expr_build_uconstant (amount));
841 stmp->bsym->flags |= BSF_SRELC;
843 stmp->bsym->flags |= BSF_RELC;
845 /* Then wrap that in a "symbol expr" for good measure. */
846 new_exp = xmalloc (sizeof (expressionS));
847 memset (new_exp, 0, sizeof (expressionS));
848 new_exp->X_op = O_symbol;
849 new_exp->X_op_symbol = 0;
850 new_exp->X_add_symbol = stmp;
851 new_exp->X_add_number = 0;
858 /* Apply a fixup to the object code. This is called for all the
859 fixups we generated by the call to fix_new_exp, above. In the call
860 above we used a reloc code which was the largest legal reloc code
861 plus the operand index. Here we undo that to recover the operand
862 index. At this point all symbol values should be fully resolved,
863 and we attempt to completely resolve the reloc. If we can not do
864 that, we determine the correct reloc code and put it back in the fixup. */
866 /* FIXME: This function handles some of the fixups and bfd_install_relocation
867 handles the rest. bfd_install_relocation (or some other bfd function)
868 should handle them all. */
871 gas_cgen_md_apply_fix (fixP, valP, seg)
874 segT seg ATTRIBUTE_UNUSED;
876 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
877 valueT value = * valP;
878 /* Canonical name, since used a lot. */
879 CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
881 if (fixP->fx_addsy == (symbolS *) NULL)
884 /* We don't actually support subtracting a symbol. */
885 if (fixP->fx_subsy != (symbolS *) NULL)
886 as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
888 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
890 int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
891 const CGEN_OPERAND *operand = cgen_operand_lookup_by_num (cd, opindex);
893 bfd_reloc_code_real_type reloc_type;
894 CGEN_FIELDS *fields = alloca (CGEN_CPU_SIZEOF_FIELDS (cd));
895 const CGEN_INSN *insn = fixP->fx_cgen.insn;
896 #ifdef OBJ_COMPLEX_RELC
901 if (fixP->fx_cgen.field)
903 /* Use the twisty little pointer path
904 back to the ifield if it exists. */
905 start = fixP->fx_cgen.field->val.leaf->start;
906 length = fixP->fx_cgen.field->val.leaf->length;
910 /* Or the far less useful operand-size guesstimate. */
911 start = operand->start;
912 length = operand->length;
915 /* FIXME: this is not a perfect heuristic for figuring out
916 whether an operand is signed: it only works when the operand
917 is an immediate. it's not terribly likely that any other
918 values will be signed relocs, but it's possible. */
919 if (operand && (operand->hw_type == HW_H_SINT))
923 /* If the reloc has been fully resolved finish the operand here. */
924 /* FIXME: This duplicates the capabilities of code in BFD. */
926 /* FIXME: If partial_inplace isn't set bfd_install_relocation won't
927 finish the job. Testing for pcrel is a temporary hack. */
930 CGEN_CPU_SET_FIELDS_BITSIZE (cd) (fields, CGEN_INSN_BITSIZE (insn));
931 CGEN_CPU_SET_VMA_OPERAND (cd) (cd, opindex, fields, (bfd_vma) value);
935 CGEN_INSN_INT insn_value =
936 cgen_get_insn_value (cd, (unsigned char *) where,
937 CGEN_INSN_BITSIZE (insn));
939 /* ??? 0 is passed for `pc'. */
940 errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
941 &insn_value, (bfd_vma) 0);
942 cgen_put_insn_value (cd, (unsigned char *) where,
943 CGEN_INSN_BITSIZE (insn), insn_value);
946 /* ??? 0 is passed for `pc'. */
947 errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
948 (unsigned char *) where,
952 as_bad_where (fixP->fx_file, fixP->fx_line, "%s", errmsg);
958 /* The operand isn't fully resolved. Determine a BFD reloc value
959 based on the operand information and leave it to
960 bfd_install_relocation. Note that this doesn't work when
961 partial_inplace == false. */
963 reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
964 #ifdef OBJ_COMPLEX_RELC
965 if (reloc_type == BFD_RELOC_RELC)
967 /* Change addend to "self-describing" form,
968 for BFD to handle in the linker. */
969 value = gas_cgen_encode_addend (start, operand->length,
970 length, fixP->fx_size,
971 cd->insn_chunk_bitsize / 8,
973 ! (fixP->fx_cgen.msb_field_p));
977 if (reloc_type != BFD_RELOC_NONE)
978 fixP->fx_r_type = reloc_type;
981 as_bad_where (fixP->fx_file, fixP->fx_line,
982 _("unresolved expression that must be resolved"));
987 else if (fixP->fx_done)
989 /* We're finished with this fixup. Install it because
990 bfd_install_relocation won't be called to do it. */
991 switch (fixP->fx_r_type)
994 md_number_to_chars (where, value, 1);
997 md_number_to_chars (where, value, 2);
1000 md_number_to_chars (where, value, 4);
1003 md_number_to_chars (where, value, 8);
1006 as_bad_where (fixP->fx_file, fixP->fx_line,
1007 _("internal error: can't install fix for reloc type %d (`%s')"),
1008 fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
1013 bfd_install_relocation will be called to finish things up. */
1015 /* Tuck `value' away for use by tc_gen_reloc.
1016 See the comment describing fx_addnumber in write.h.
1017 This field is misnamed (or misused :-). */
1018 fixP->fx_addnumber = value;
1021 bfd_reloc_code_real_type
1022 gas_cgen_pcrel_r_type (bfd_reloc_code_real_type r)
1026 case BFD_RELOC_8: r = BFD_RELOC_8_PCREL; break;
1027 case BFD_RELOC_16: r = BFD_RELOC_16_PCREL; break;
1028 case BFD_RELOC_24: r = BFD_RELOC_24_PCREL; break;
1029 case BFD_RELOC_32: r = BFD_RELOC_32_PCREL; break;
1030 case BFD_RELOC_64: r = BFD_RELOC_64_PCREL; break;
1037 /* Translate internal representation of relocation info to BFD target format.
1039 FIXME: To what extent can we get all relevant targets to use this? */
1042 gas_cgen_tc_gen_reloc (section, fixP)
1043 asection * section ATTRIBUTE_UNUSED;
1046 bfd_reloc_code_real_type r_type = fixP->fx_r_type;
1049 reloc = (arelent *) xmalloc (sizeof (arelent));
1051 #ifdef GAS_CGEN_PCREL_R_TYPE
1053 r_type = GAS_CGEN_PCREL_R_TYPE (r_type);
1055 reloc->howto = bfd_reloc_type_lookup (stdoutput, r_type);
1057 if (reloc->howto == (reloc_howto_type *) NULL)
1059 as_bad_where (fixP->fx_file, fixP->fx_line,
1060 _("relocation is not supported"));
1064 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1066 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1067 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1069 /* Use fx_offset for these cases. */
1070 if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
1071 || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
1072 reloc->addend = fixP->fx_offset;
1074 reloc->addend = fixP->fx_addnumber;
1076 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1080 /* Perform any cgen specific initialisation.
1081 Called after gas_cgen_cpu_desc has been created. */
1086 if (flag_signed_overflow_ok)
1087 cgen_set_signed_overflow_ok (gas_cgen_cpu_desc);
1089 cgen_clear_signed_overflow_ok (gas_cgen_cpu_desc);