1 /* GAS interface for targets using CGEN: Cpu tools GENerator.
2 Copyright (C) 1996-2024 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"
30 #ifdef OBJ_COMPLEX_RELC
31 static expressionS
* make_right_shifted_expr
32 (expressionS
*, const int, const int);
34 static unsigned long gas_cgen_encode_addend
35 (const unsigned long, const unsigned long, const unsigned long, \
36 const unsigned long, const unsigned long, const unsigned long, \
39 static const char * weak_operand_overflow_check
40 (const expressionS
*, const CGEN_OPERAND
*);
42 static void queue_fixup_recursively
43 (const int, const int, expressionS
*, \
44 const CGEN_MAYBE_MULTI_IFLD
*, const int, const int);
46 static int rightshift
= 0;
48 static void queue_fixup (int, int, expressionS
*);
50 /* Opcode table descriptor, must be set by md_begin. */
52 CGEN_CPU_DESC gas_cgen_cpu_desc
;
54 /* Callback to insert a register into the symbol table.
55 A target may choose to let GAS parse the registers.
56 ??? Not currently used. */
59 cgen_asm_record_register (char *name
, int number
)
61 /* Use symbol_create here instead of symbol_new so we don't try to
62 output registers into the object file's symbol table. */
63 symbol_table_insert (symbol_create (name
, reg_section
,
64 &zero_address_frag
, number
));
67 /* We need to keep a list of fixups. We can't simply generate them as
68 we go, because that would require us to first create the frag, and
69 that would screw up references to ``.''.
71 This is used by cpu's with simple operands. It keeps knowledge of what
72 an `expressionS' is and what a `fixup' is out of CGEN which for the time
75 OPINDEX is the index in the operand table.
76 OPINFO is something the caller chooses to help in reloc determination. */
83 struct cgen_maybe_multi_ifield
* field
;
87 static struct fixup fixups
[GAS_CGEN_MAX_FIXUPS
];
88 static int num_fixups
;
90 /* Prepare to parse an instruction.
91 ??? May wish to make this static and delete calls in md_assemble. */
94 gas_cgen_init_parse (void)
102 queue_fixup (int opindex
, int opinfo
, expressionS
*expP
)
104 /* We need to generate a fixup for this expression. */
105 if (num_fixups
>= GAS_CGEN_MAX_FIXUPS
)
106 as_fatal (_("too many fixups"));
107 fixups
[num_fixups
].exp
= *expP
;
108 fixups
[num_fixups
].opindex
= opindex
;
109 fixups
[num_fixups
].opinfo
= opinfo
;
113 /* The following functions allow fixup chains to be stored, retrieved,
114 and swapped. They are a generalization of a pre-existing scheme
115 for storing, restoring and swapping fixup chains that was used by
116 the m32r port. The functionality is essentially the same, only
117 instead of only being able to store a single fixup chain, an entire
118 array of fixup chains can be stored. It is the user's responsibility
119 to keep track of how many fixup chains have been stored and which
120 elements of the array they are in.
122 The algorithms used are the same as in the old scheme. Other than the
123 "array-ness" of the whole thing, the functionality is identical to the
126 gas_cgen_initialize_saved_fixups_array():
127 Sets num_fixups_in_chain to 0 for each element. Call this from
128 md_begin() if you plan to use these functions and you want the
129 fixup count in each element to be set to 0 initially. This is
130 not necessary, but it's included just in case. It performs
131 the same function for each element in the array of fixup chains
132 that gas_init_parse() performs for the current fixups.
134 gas_cgen_save_fixups (element):
135 element - element number of the array you wish to store the fixups
136 to. No mechanism is built in for tracking what element
139 gas_cgen_restore_fixups (element):
140 element - element number of the array you wish to restore the fixups
143 gas_cgen_swap_fixups(int element):
144 element - swap the current fixups with those in this element number.
149 struct fixup fixup_chain
[GAS_CGEN_MAX_FIXUPS
];
150 int num_fixups_in_chain
;
153 static struct saved_fixups stored_fixups
[MAX_SAVED_FIXUP_CHAINS
];
156 gas_cgen_initialize_saved_fixups_array (void)
160 while (i
< MAX_SAVED_FIXUP_CHAINS
)
161 stored_fixups
[i
++].num_fixups_in_chain
= 0;
165 gas_cgen_save_fixups (int i
)
167 if (i
< 0 || i
>= MAX_SAVED_FIXUP_CHAINS
)
169 as_fatal ("index into stored_fixups[] out of bounds");
173 stored_fixups
[i
].num_fixups_in_chain
= num_fixups
;
174 memcpy (stored_fixups
[i
].fixup_chain
, fixups
,
175 sizeof (fixups
[0]) * num_fixups
);
180 gas_cgen_restore_fixups (int i
)
182 if (i
< 0 || i
>= MAX_SAVED_FIXUP_CHAINS
)
184 as_fatal ("index into stored_fixups[] out of bounds");
188 num_fixups
= stored_fixups
[i
].num_fixups_in_chain
;
189 memcpy (fixups
, stored_fixups
[i
].fixup_chain
,
190 (sizeof (stored_fixups
[i
].fixup_chain
[0])) * num_fixups
);
191 stored_fixups
[i
].num_fixups_in_chain
= 0;
195 gas_cgen_swap_fixups (int i
)
197 if (i
< 0 || i
>= MAX_SAVED_FIXUP_CHAINS
)
199 as_fatal ("index into stored_fixups[] out of bounds");
204 gas_cgen_restore_fixups (i
);
206 else if (stored_fixups
[i
].num_fixups_in_chain
== 0)
207 gas_cgen_save_fixups (i
);
212 struct fixup tmp_fixup
;
214 tmp
= stored_fixups
[i
].num_fixups_in_chain
;
215 stored_fixups
[i
].num_fixups_in_chain
= num_fixups
;
218 for (tmp
= GAS_CGEN_MAX_FIXUPS
; tmp
--;)
220 tmp_fixup
= stored_fixups
[i
].fixup_chain
[tmp
];
221 stored_fixups
[i
].fixup_chain
[tmp
] = fixups
[tmp
];
222 fixups
[tmp
] = tmp_fixup
;
227 /* Default routine to record a fixup.
228 This is a cover function to fix_new.
229 It exists because we record INSN with the fixup.
231 FRAG and WHERE are their respective arguments to fix_new_exp.
233 OPINFO is something the caller chooses to help in reloc determination.
235 At this point we do not use a bfd_reloc_code_real_type for
236 operands residing in the insn, but instead just use the
237 operand index. This lets us easily handle fixups for any
238 operand type. We pick a BFD reloc type in md_apply_fix. */
241 gas_cgen_record_fixup (fragS
*frag
, int where
, const CGEN_INSN
*insn
,
242 int length
, const CGEN_OPERAND
*operand
, int opinfo
,
243 symbolS
*symbol
, offsetT offset
)
247 /* It may seem strange to use operand->attrs and not insn->attrs here,
248 but it is the operand that has a pc relative relocation. */
249 fixP
= fix_new (frag
, where
, length
/ 8, symbol
, offset
,
250 CGEN_OPERAND_ATTR_VALUE (operand
, CGEN_OPERAND_PCREL_ADDR
),
251 (bfd_reloc_code_real_type
)
252 ((int) BFD_RELOC_UNUSED
253 + (int) operand
->type
));
254 fixP
->fx_cgen
.insn
= insn
;
255 fixP
->fx_cgen
.opinfo
= opinfo
;
256 fixP
->fx_cgen
.field
= NULL
;
257 fixP
->fx_cgen
.msb_field_p
= 0;
262 /* Default routine to record a fixup given an expression.
263 This is a cover function to fix_new_exp.
264 It exists because we record INSN with the fixup.
266 FRAG and WHERE are their respective arguments to fix_new_exp.
268 OPINFO is something the caller chooses to help in reloc determination.
270 At this point we do not use a bfd_reloc_code_real_type for
271 operands residing in the insn, but instead just use the
272 operand index. This lets us easily handle fixups for any
273 operand type. We pick a BFD reloc type in md_apply_fix. */
276 gas_cgen_record_fixup_exp (fragS
*frag
, int where
, const CGEN_INSN
*insn
,
277 int length
, const CGEN_OPERAND
*operand
, int opinfo
,
282 /* It may seem strange to use operand->attrs and not insn->attrs here,
283 but it is the operand that has a pc relative relocation. */
284 fixP
= fix_new_exp (frag
, where
, length
/ 8, exp
,
285 CGEN_OPERAND_ATTR_VALUE (operand
, CGEN_OPERAND_PCREL_ADDR
),
286 (bfd_reloc_code_real_type
)
287 ((int) BFD_RELOC_UNUSED
288 + (int) operand
->type
));
289 fixP
->fx_cgen
.insn
= insn
;
290 fixP
->fx_cgen
.opinfo
= opinfo
;
291 fixP
->fx_cgen
.field
= NULL
;
292 fixP
->fx_cgen
.msb_field_p
= 0;
297 #ifdef OBJ_COMPLEX_RELC
299 expr_build_binary (operatorT op
, symbolS
* s1
, symbolS
* s2
)
307 return make_expr_symbol (& e
);
311 /* Used for communication between the next two procedures. */
312 static jmp_buf expr_jmp_buf
;
313 static int expr_jmp_buf_p
;
315 /* Callback for cgen interface. Parse the expression at *STRP.
316 The result is an error message or NULL for success (in which case
317 *STRP is advanced past the parsed text).
318 WANT is an indication of what the caller is looking for.
319 If WANT == CGEN_ASM_PARSE_INIT the caller is beginning to try to match
320 a table entry with the insn, reset the queued fixups counter.
321 An enum cgen_parse_operand_result is stored in RESULTP.
322 OPINDEX is the operand's table entry index.
323 OPINFO is something the caller chooses to help in reloc determination.
324 The resulting value is stored in VALUEP. */
327 gas_cgen_parse_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
,
328 enum cgen_parse_operand_type want
, const char **strP
,
329 int opindex
, int opinfo
,
330 enum cgen_parse_operand_result
*resultP
,
334 /* These are volatile to survive the setjmp. */
335 char * volatile hold
;
336 enum cgen_parse_operand_result
* volatile resultP_1
;
337 volatile int opinfo_1
;
340 static enum cgen_parse_operand_result
*resultP_1
;
346 #ifdef OBJ_COMPLEX_RELC
347 volatile int signed_p
= 0;
348 symbolS
* stmp
= NULL
;
349 bfd_reloc_code_real_type reloc_type
;
350 const CGEN_OPERAND
* operand
;
353 if (want
== CGEN_PARSE_OPERAND_INIT
)
355 gas_cgen_init_parse ();
360 hold
= input_line_pointer
;
361 input_line_pointer
= (char *) *strP
;
364 /* We rely on md_operand to longjmp back to us.
365 This is done via gas_cgen_md_operand. */
366 if (setjmp (expr_jmp_buf
) != 0)
369 input_line_pointer
= (char *) hold
;
370 *resultP_1
= CGEN_PARSE_OPERAND_RESULT_ERROR
;
371 return _("illegal operand");
379 *strP
= input_line_pointer
;
380 input_line_pointer
= hold
;
382 #ifdef TC_CGEN_PARSE_FIX_EXP
383 opinfo_1
= TC_CGEN_PARSE_FIX_EXP (opinfo_1
, & exp
);
386 /* FIXME: Need to check `want'. */
388 resolve_register (&exp
);
393 errmsg
= _("illegal operand");
394 *resultP
= CGEN_PARSE_OPERAND_RESULT_ERROR
;
397 errmsg
= _("missing operand");
398 *resultP
= CGEN_PARSE_OPERAND_RESULT_ERROR
;
401 if (want
== CGEN_PARSE_OPERAND_SYMBOLIC
)
403 *valueP
= exp
.X_add_number
;
404 *resultP
= CGEN_PARSE_OPERAND_RESULT_NUMBER
;
407 *valueP
= exp
.X_add_number
;
408 *resultP
= CGEN_PARSE_OPERAND_RESULT_REGISTER
;
412 #ifdef OBJ_COMPLEX_RELC
413 /* Look up operand, check to see if there's an obvious
414 overflow (this helps disambiguate some insn parses). */
415 operand
= cgen_operand_lookup_by_num (cd
, opindex
);
416 errmsg
= weak_operand_overflow_check (& exp
, operand
);
422 /* Fragment the expression as necessary, and queue a reloc. */
423 memset (& dummy_fixup
, 0, sizeof (fixS
));
425 reloc_type
= md_cgen_lookup_reloc (0, operand
, & dummy_fixup
);
427 if (exp
.X_op
== O_symbol
428 && reloc_type
== BFD_RELOC_RELC
429 && symbol_constant_p (exp
.X_add_symbol
)
430 && (!symbol_symbolS (exp
.X_add_symbol
)
431 || (bsym
= symbol_get_bfdsym (exp
.X_add_symbol
)) == NULL
432 || (bsym
->section
!= expr_section
433 && bsym
->section
!= absolute_section
434 && bsym
->section
!= undefined_section
)))
436 /* Local labels will have been (eagerly) turned into constants
437 by now, due to the inappropriately deep insight of the
438 expression parser. Unfortunately make_expr_symbol
439 prematurely dives into the symbol evaluator, and in this
440 case it gets a bad answer, so we manually create the
441 expression symbol we want here. */
442 stmp
= symbol_create (FAKE_LABEL_NAME
, expr_section
,
443 &zero_address_frag
, 0);
444 symbol_set_value_expression (stmp
, & exp
);
447 stmp
= make_expr_symbol (& exp
);
449 /* If this is a pc-relative RELC operand, we
450 need to subtract "." from the expression. */
451 if (reloc_type
== BFD_RELOC_RELC
452 && CGEN_OPERAND_ATTR_VALUE (operand
, CGEN_OPERAND_PCREL_ADDR
))
453 stmp
= expr_build_binary (O_subtract
, stmp
, expr_build_dot ());
455 /* FIXME: this is not a perfect heuristic for figuring out
456 whether an operand is signed: it only works when the operand
457 is an immediate. it's not terribly likely that any other
458 values will be signed relocs, but it's possible. */
459 if (operand
&& (operand
->hw_type
== HW_H_SINT
))
462 if (symbol_symbolS (stmp
)
463 && (bsym
= symbol_get_bfdsym (stmp
)) != NULL
464 && bsym
->section
== expr_section
465 && ! S_IS_LOCAL (stmp
))
468 bsym
->flags
|= BSF_SRELC
;
470 bsym
->flags
|= BSF_RELC
;
473 /* Now package it all up for the fixup emitter. */
476 exp
.X_add_symbol
= stmp
;
477 exp
.X_add_number
= 0;
479 /* Re-init rightshift quantity, just in case. */
480 rightshift
= operand
->length
;
481 queue_fixup_recursively (opindex
, opinfo_1
, & exp
,
482 (reloc_type
== BFD_RELOC_RELC
) ?
483 & (operand
->index_fields
) : 0,
487 ? CGEN_PARSE_OPERAND_RESULT_ERROR
488 : CGEN_PARSE_OPERAND_RESULT_QUEUED
;
491 queue_fixup (opindex
, opinfo_1
, &exp
);
493 *resultP
= CGEN_PARSE_OPERAND_RESULT_QUEUED
;
501 /* md_operand handler to catch unrecognized expressions and halt the
502 parsing process so the next entry can be tried.
504 ??? This could be done differently by adding code to `expression'. */
507 gas_cgen_md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
509 /* Don't longjmp if we're not called from within cgen_parse_operand(). */
511 longjmp (expr_jmp_buf
, 1);
514 /* Finish assembling instruction INSN.
515 BUF contains what we've built up so far.
516 LENGTH is the size of the insn in bits.
517 RELAX_P is non-zero if relaxable insns should be emitted as such.
518 Otherwise they're emitted in non-relaxable forms.
519 The "result" is stored in RESULT if non-NULL. */
522 gas_cgen_finish_insn (const CGEN_INSN
*insn
, CGEN_INSN_BYTES_PTR buf
,
523 unsigned int length
, int relax_p
, finished_insnS
*result
)
528 unsigned int byte_len
= length
/ 8;
530 /* ??? Target foo issues various warnings here, so one might want to provide
531 a hook here. However, our caller is defined in tc-foo.c so there
532 shouldn't be a need for a hook. */
534 /* Write out the instruction.
535 It is important to fetch enough space in one call to `frag_more'.
536 We use (f - frag_now->fr_literal) to compute where we are and we
537 don't want frag_now to change between calls.
539 Relaxable instructions: We need to ensure we allocate enough
540 space for the largest insn. */
542 if (CGEN_INSN_ATTR_VALUE (insn
, CGEN_INSN_RELAXED
))
543 /* These currently shouldn't get here. */
546 /* Is there a relaxable insn with the relaxable operand needing a fixup? */
549 if (relax_p
&& CGEN_INSN_ATTR_VALUE (insn
, CGEN_INSN_RELAXABLE
))
551 /* Scan the fixups for the operand affected by relaxing
552 (i.e. the branch address). */
554 for (i
= 0; i
< num_fixups
; ++i
)
556 if (CGEN_OPERAND_ATTR_VALUE (cgen_operand_lookup_by_num (gas_cgen_cpu_desc
, fixups
[i
].opindex
),
565 if (relax_operand
!= -1)
573 #ifdef TC_CGEN_MAX_RELAX
574 max_len
= TC_CGEN_MAX_RELAX (insn
, byte_len
);
576 max_len
= CGEN_MAX_INSN_SIZE
;
578 /* Ensure variable part and fixed part are in same fragment. */
579 /* FIXME: Having to do this seems like a hack. */
582 /* Allocate space for the fixed part. */
583 f
= frag_more (byte_len
);
585 /* Create a relaxable fragment for this instruction. */
588 exp
= &fixups
[relax_operand
].exp
;
589 sym
= exp
->X_add_symbol
;
590 off
= exp
->X_add_number
;
591 if (exp
->X_op
!= O_constant
&& exp
->X_op
!= O_symbol
)
593 /* Handle complex expressions. */
594 sym
= make_expr_symbol (exp
);
598 frag_var (rs_machine_dependent
,
599 max_len
- byte_len
/* max chars */,
600 0 /* variable part already allocated */,
601 /* FIXME: When we machine generate the relax table,
602 machine generate a macro to compute subtype. */
608 /* Record the operand number with the fragment so md_convert_frag
609 can use gas_cgen_md_record_fixup to record the appropriate reloc. */
610 old_frag
->fr_cgen
.insn
= insn
;
611 old_frag
->fr_cgen
.opindex
= fixups
[relax_operand
].opindex
;
612 old_frag
->fr_cgen
.opinfo
= fixups
[relax_operand
].opinfo
;
614 result
->frag
= old_frag
;
618 f
= frag_more (byte_len
);
620 result
->frag
= frag_now
;
623 /* If we're recording insns as numbers (rather than a string of bytes),
624 target byte order handling is deferred until now. */
626 cgen_put_insn_value (gas_cgen_cpu_desc
, (unsigned char *) f
, length
, *buf
,
627 gas_cgen_cpu_desc
->insn_endian
);
629 memcpy (f
, buf
, byte_len
);
632 /* Emit DWARF2 debugging information. */
633 dwarf2_emit_insn (byte_len
);
635 /* Create any fixups. */
636 for (i
= 0; i
< num_fixups
; ++i
)
639 const CGEN_OPERAND
*operand
=
640 cgen_operand_lookup_by_num (gas_cgen_cpu_desc
, fixups
[i
].opindex
);
642 /* Don't create fixups for these. That's done during relaxation.
643 We don't need to test for CGEN_INSN_RELAXED as they can't get here
646 && CGEN_INSN_ATTR_VALUE (insn
, CGEN_INSN_RELAXABLE
)
647 && CGEN_OPERAND_ATTR_VALUE (operand
, CGEN_OPERAND_RELAX
))
650 #ifndef md_cgen_record_fixup_exp
651 #define md_cgen_record_fixup_exp gas_cgen_record_fixup_exp
654 fixP
= md_cgen_record_fixup_exp (frag_now
, f
- frag_now
->fr_literal
,
655 insn
, length
, operand
,
658 fixP
->fx_cgen
.field
= fixups
[i
].field
;
659 fixP
->fx_cgen
.msb_field_p
= fixups
[i
].msb_field_p
;
661 result
->fixups
[i
] = fixP
;
666 result
->num_fixups
= num_fixups
;
671 #ifdef OBJ_COMPLEX_RELC
672 /* Queue many fixups, recursively. If the field is a multi-ifield,
673 repeatedly queue its sub-parts, right shifted to fit into the field (we
674 assume here multi-fields represent a left-to-right, MSB0-LSB0
678 queue_fixup_recursively (const int opindex
,
681 const CGEN_MAYBE_MULTI_IFLD
* field
,
683 const int part_of_multi
)
685 if (field
&& field
->count
)
689 for (i
= 0; i
< field
->count
; ++ i
)
690 queue_fixup_recursively (opindex
, opinfo
, expP
,
691 & (field
->val
.multi
[i
]), signed_p
, i
);
695 expressionS
* new_exp
= expP
;
698 printf ("queueing fixup for field %s\n",
699 (field
? field
->val
.leaf
->name
: "??"));
700 print_symbol_value (expP
->X_add_symbol
);
702 if (field
&& part_of_multi
!= -1)
704 rightshift
-= field
->val
.leaf
->length
;
706 /* Shift reloc value by number of bits remaining after this
709 new_exp
= make_right_shifted_expr (expP
, rightshift
, signed_p
);
712 /* Truncate reloc values to length, *after* leftmost one. */
713 fixups
[num_fixups
].msb_field_p
= (part_of_multi
<= 0);
714 fixups
[num_fixups
].field
= (CGEN_MAYBE_MULTI_IFLD
*) field
;
716 queue_fixup (opindex
, opinfo
, new_exp
);
720 /* Encode the self-describing RELC reloc format's addend. */
723 gas_cgen_encode_addend (const unsigned long start
, /* in bits */
724 const unsigned long len
, /* in bits */
725 const unsigned long oplen
, /* in bits */
726 const unsigned long wordsz
, /* in bytes */
727 const unsigned long chunksz
, /* in bytes */
728 const unsigned long signed_p
,
729 const unsigned long trunc_p
)
731 unsigned long res
= 0L;
734 res
|= (oplen
& 0x3F) << 6;
735 res
|= (len
& 0x3F) << 12;
736 res
|= (wordsz
& 0xF) << 18;
737 res
|= (chunksz
& 0xF) << 22;
738 res
|= (CGEN_INSN_LSB0_P
? 1 : 0) << 27;
739 res
|= signed_p
<< 28;
740 res
|= trunc_p
<< 29;
745 /* Purpose: make a weak check that the expression doesn't overflow the
746 operand it's to be inserted into.
748 Rationale: some insns used to use %operators to disambiguate during a
749 parse. when these %operators are translated to expressions by the macro
750 expander, the ambiguity returns. we attempt to disambiguate by field
753 Method: check to see if the expression's top node is an O_and operator,
754 and the mask is larger than the operand length. This would be an
755 overflow, so signal it by returning an error string. Any other case is
756 ambiguous, so we assume it's OK and return NULL. */
759 weak_operand_overflow_check (const expressionS
* exp
,
760 const CGEN_OPERAND
* operand
)
762 const unsigned long len
= operand
->length
;
764 unsigned long opmask
= len
== 0 ? 0 : (1UL << (len
- 1) << 1) - 1;
769 if (exp
->X_op
!= O_bit_and
)
771 /* Check for implicit overflow flag. */
772 if (CGEN_OPERAND_ATTR_VALUE
773 (operand
, CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW
))
774 return _("a reloc on this operand implies an overflow");
778 mask
= exp
->X_add_number
;
780 if (exp
->X_add_symbol
781 && symbol_constant_p (exp
->X_add_symbol
))
782 mask
|= *symbol_X_add_number (exp
->X_add_symbol
);
785 && symbol_constant_p (exp
->X_op_symbol
))
786 mask
|= *symbol_X_add_number (exp
->X_op_symbol
);
788 /* Want to know if mask covers more bits than opmask.
789 this is the same as asking if mask has any bits not in opmask,
790 or whether (mask & ~opmask) is nonzero. */
791 if (mask
&& (mask
& ~opmask
))
794 printf ("overflow: (mask = %8.8x, ~opmask = %8.8x, AND = %8.8x)\n",
795 mask
, ~opmask
, (mask
& ~opmask
));
797 return _("operand mask overflow");
804 make_right_shifted_expr (expressionS
* exp
,
809 expressionS
* new_exp
;
812 stmp
= expr_build_binary (O_right_shift
,
813 make_expr_symbol (exp
),
814 expr_build_uconstant (amount
));
815 bsym
= symbol_get_bfdsym (stmp
);
818 bsym
->flags
|= BSF_SRELC
;
820 bsym
->flags
|= BSF_RELC
;
822 /* Then wrap that in a "symbol expr" for good measure. */
823 new_exp
= XNEW (expressionS
);
824 memset (new_exp
, 0, sizeof (expressionS
));
825 new_exp
->X_op
= O_symbol
;
826 new_exp
->X_op_symbol
= 0;
827 new_exp
->X_add_symbol
= stmp
;
828 new_exp
->X_add_number
= 0;
835 /* Apply a fixup to the object code. This is called for all the
836 fixups we generated by the call to fix_new_exp, above. In the call
837 above we used a reloc code which was the largest legal reloc code
838 plus the operand index. Here we undo that to recover the operand
839 index. At this point all symbol values should be fully resolved,
840 and we attempt to completely resolve the reloc. If we can not do
841 that, we determine the correct reloc code and put it back in the fixup. */
843 /* FIXME: This function handles some of the fixups and bfd_install_relocation
844 handles the rest. bfd_install_relocation (or some other bfd function)
845 should handle them all. */
848 gas_cgen_md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
850 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
851 valueT value
= * valP
;
852 /* Canonical name, since used a lot. */
853 CGEN_CPU_DESC cd
= gas_cgen_cpu_desc
;
855 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
858 /* We don't actually support subtracting a symbol. */
859 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
860 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("expression too complex"));
862 if ((int) fixP
->fx_r_type
>= (int) BFD_RELOC_UNUSED
)
864 int opindex
= (int) fixP
->fx_r_type
- (int) BFD_RELOC_UNUSED
;
865 const CGEN_OPERAND
*operand
= cgen_operand_lookup_by_num (cd
, opindex
);
867 bfd_reloc_code_real_type reloc_type
;
868 const CGEN_INSN
*insn
= fixP
->fx_cgen
.insn
;
869 #ifdef OBJ_COMPLEX_RELC
874 if (fixP
->fx_cgen
.field
)
876 /* Use the twisty little pointer path
877 back to the ifield if it exists. */
878 start
= fixP
->fx_cgen
.field
->val
.leaf
->start
;
879 length
= fixP
->fx_cgen
.field
->val
.leaf
->length
;
883 /* Or the far less useful operand-size guesstimate. */
884 start
= operand
->start
;
885 length
= operand
->length
;
888 /* FIXME: this is not a perfect heuristic for figuring out
889 whether an operand is signed: it only works when the operand
890 is an immediate. it's not terribly likely that any other
891 values will be signed relocs, but it's possible. */
892 if (operand
&& (operand
->hw_type
== HW_H_SINT
))
896 /* If the reloc has been fully resolved finish the operand here. */
897 /* FIXME: This duplicates the capabilities of code in BFD. */
899 /* FIXME: If partial_inplace isn't set bfd_install_relocation won't
900 finish the job. Testing for pcrel is a temporary hack. */
903 CGEN_FIELDS
*fields
= xmalloc (CGEN_CPU_SIZEOF_FIELDS (cd
));
905 CGEN_CPU_SET_FIELDS_BITSIZE (cd
) (fields
, CGEN_INSN_BITSIZE (insn
));
906 CGEN_CPU_SET_VMA_OPERAND (cd
) (cd
, opindex
, fields
, (bfd_vma
) value
);
910 CGEN_INSN_INT insn_value
=
911 cgen_get_insn_value (cd
, (unsigned char *) where
,
912 CGEN_INSN_BITSIZE (insn
),
915 /* ??? 0 is passed for `pc'. */
916 errmsg
= CGEN_CPU_INSERT_OPERAND (cd
) (cd
, opindex
, fields
,
917 &insn_value
, (bfd_vma
) 0);
918 cgen_put_insn_value (cd
, (unsigned char *) where
,
919 CGEN_INSN_BITSIZE (insn
), insn_value
,
923 /* ??? 0 is passed for `pc'. */
924 errmsg
= CGEN_CPU_INSERT_OPERAND (cd
) (cd
, opindex
, fields
,
925 (unsigned char *) where
,
929 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "%s", errmsg
);
937 /* The operand isn't fully resolved. Determine a BFD reloc value
938 based on the operand information and leave it to
939 bfd_install_relocation. Note that this doesn't work when
940 partial_inplace == false. */
942 reloc_type
= md_cgen_lookup_reloc (insn
, operand
, fixP
);
943 #ifdef OBJ_COMPLEX_RELC
944 if (reloc_type
== BFD_RELOC_RELC
)
946 /* Change addend to "self-describing" form,
947 for BFD to handle in the linker. */
948 value
= gas_cgen_encode_addend (start
, operand
->length
,
949 length
, fixP
->fx_size
,
950 cd
->insn_chunk_bitsize
/ 8,
952 ! (fixP
->fx_cgen
.msb_field_p
));
956 if (reloc_type
!= BFD_RELOC_NONE
)
957 fixP
->fx_r_type
= reloc_type
;
960 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
961 _("unresolved expression that must be resolved"));
966 else if (fixP
->fx_done
)
968 /* We're finished with this fixup. Install it because
969 bfd_install_relocation won't be called to do it. */
970 switch (fixP
->fx_r_type
)
973 md_number_to_chars (where
, value
, 1);
976 md_number_to_chars (where
, value
, 2);
979 md_number_to_chars (where
, value
, 4);
982 md_number_to_chars (where
, value
, 8);
985 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
986 _("internal error: can't install fix for reloc type %d (`%s')"),
987 fixP
->fx_r_type
, bfd_get_reloc_code_name (fixP
->fx_r_type
));
992 bfd_install_relocation will be called to finish things up. */
994 /* Tuck `value' away for use by tc_gen_reloc.
995 See the comment describing fx_addnumber in write.h.
996 This field is misnamed (or misused :-). */
997 fixP
->fx_addnumber
= value
;
1000 bfd_reloc_code_real_type
1001 gas_cgen_pcrel_r_type (bfd_reloc_code_real_type r
)
1005 case BFD_RELOC_8
: r
= BFD_RELOC_8_PCREL
; break;
1006 case BFD_RELOC_16
: r
= BFD_RELOC_16_PCREL
; break;
1007 case BFD_RELOC_24
: r
= BFD_RELOC_24_PCREL
; break;
1008 case BFD_RELOC_32
: r
= BFD_RELOC_32_PCREL
; break;
1009 case BFD_RELOC_64
: r
= BFD_RELOC_64_PCREL
; break;
1016 /* Translate internal representation of relocation info to BFD target format.
1018 FIXME: To what extent can we get all relevant targets to use this? */
1021 gas_cgen_tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
1023 bfd_reloc_code_real_type r_type
= fixP
->fx_r_type
;
1026 reloc
= XNEW (arelent
);
1028 #ifdef GAS_CGEN_PCREL_R_TYPE
1030 r_type
= GAS_CGEN_PCREL_R_TYPE (r_type
);
1032 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, r_type
);
1034 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
1036 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1037 _("relocation is not supported"));
1041 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1043 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
1044 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
1046 /* Use fx_offset for these cases. */
1047 if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
1048 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
)
1049 reloc
->addend
= fixP
->fx_offset
;
1051 reloc
->addend
= fixP
->fx_addnumber
;
1053 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1057 /* Perform any cgen specific initialisation.
1058 Called after gas_cgen_cpu_desc has been created. */
1061 gas_cgen_begin (void)
1063 if (flag_signed_overflow_ok
)
1064 cgen_set_signed_overflow_ok (gas_cgen_cpu_desc
);
1066 cgen_clear_signed_overflow_ok (gas_cgen_cpu_desc
);