cgen.c revision 1.1.1.8 1 /* GAS interface for targets using CGEN: Cpu tools GENerator.
2 Copyright (C) 1996-2025 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, 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.
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 the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
19
20 #include "as.h"
21 #include <setjmp.h>
22 #include "symcat.h"
23 #include "cgen-desc.h"
24 #include "subsegs.h"
25 #include "cgen.h"
26 #include "dwarf2dbg.h"
27
28 #include "symbols.h"
29
30 #ifdef OBJ_COMPLEX_RELC
31 static expressionS * make_right_shifted_expr
32 (expressionS *, const int, const int);
33
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, \
37 const unsigned long);
38
39 static const char * weak_operand_overflow_check
40 (const expressionS *, const CGEN_OPERAND *);
41
42 static void queue_fixup_recursively
43 (const int, const int, expressionS *, \
44 const CGEN_MAYBE_MULTI_IFLD *, const int, const int);
45
46 static int rightshift = 0;
47 #endif
48 static void queue_fixup (int, int, expressionS *);
49
50 /* Opcode table descriptor, must be set by md_begin. */
51
52 CGEN_CPU_DESC gas_cgen_cpu_desc;
53
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. */
57
58 void
59 cgen_asm_record_register (char *name, int number)
60 {
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));
65 }
66
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 ``.''.
70
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
73 being is preferable.
74
75 OPINDEX is the index in the operand table.
76 OPINFO is something the caller chooses to help in reloc determination. */
77
78 struct fixup
79 {
80 int opindex;
81 int opinfo;
82 expressionS exp;
83 struct cgen_maybe_multi_ifield * field;
84 int msb_field_p;
85 };
86
87 static struct fixup fixups[GAS_CGEN_MAX_FIXUPS];
88 static int num_fixups;
89
90 /* Prepare to parse an instruction.
91 ??? May wish to make this static and delete calls in md_assemble. */
92
93 void
94 gas_cgen_init_parse (void)
95 {
96 num_fixups = 0;
97 }
98
99 /* Queue a fixup. */
100
101 static void
102 queue_fixup (int opindex, int opinfo, expressionS *expP)
103 {
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;
110 ++ num_fixups;
111 }
112
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.
121
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
124 old scheme.
125
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.
133
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
137 was last stored to.
138
139 gas_cgen_restore_fixups (element):
140 element - element number of the array you wish to restore the fixups
141 from.
142
143 gas_cgen_swap_fixups(int element):
144 element - swap the current fixups with those in this element number.
145 */
146
147 struct saved_fixups
148 {
149 struct fixup fixup_chain[GAS_CGEN_MAX_FIXUPS];
150 int num_fixups_in_chain;
151 };
152
153 static struct saved_fixups stored_fixups[MAX_SAVED_FIXUP_CHAINS];
154
155 void
156 gas_cgen_initialize_saved_fixups_array (void)
157 {
158 int i = 0;
159
160 while (i < MAX_SAVED_FIXUP_CHAINS)
161 stored_fixups[i++].num_fixups_in_chain = 0;
162 }
163
164 void
165 gas_cgen_save_fixups (int i)
166 {
167 if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
168 {
169 as_fatal ("index into stored_fixups[] out of bounds");
170 return;
171 }
172
173 stored_fixups[i].num_fixups_in_chain = num_fixups;
174 memcpy (stored_fixups[i].fixup_chain, fixups,
175 sizeof (fixups[0]) * num_fixups);
176 num_fixups = 0;
177 }
178
179 void
180 gas_cgen_restore_fixups (int i)
181 {
182 if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
183 {
184 as_fatal ("index into stored_fixups[] out of bounds");
185 return;
186 }
187
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;
192 }
193
194 void
195 gas_cgen_swap_fixups (int i)
196 {
197 if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
198 {
199 as_fatal ("index into stored_fixups[] out of bounds");
200 return;
201 }
202
203 if (num_fixups == 0)
204 gas_cgen_restore_fixups (i);
205
206 else if (stored_fixups[i].num_fixups_in_chain == 0)
207 gas_cgen_save_fixups (i);
208
209 else
210 {
211 int tmp;
212 struct fixup tmp_fixup;
213
214 tmp = stored_fixups[i].num_fixups_in_chain;
215 stored_fixups[i].num_fixups_in_chain = num_fixups;
216 num_fixups = tmp;
217
218 for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;)
219 {
220 tmp_fixup = stored_fixups[i].fixup_chain [tmp];
221 stored_fixups[i].fixup_chain[tmp] = fixups [tmp];
222 fixups [tmp] = tmp_fixup;
223 }
224 }
225 }
226
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.
230
231 FRAG and WHERE are their respective arguments to fix_new_exp.
232 LENGTH is in bits.
233 OPINFO is something the caller chooses to help in reloc determination.
234
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. */
239
240 fixS *
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)
244 {
245 fixS *fixP;
246
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_UNUSED + operand->type);
252 fixP->fx_cgen.insn = insn;
253 fixP->fx_cgen.opinfo = opinfo;
254 fixP->fx_cgen.field = NULL;
255 fixP->fx_cgen.msb_field_p = 0;
256
257 return fixP;
258 }
259
260 /* Default routine to record a fixup given an expression.
261 This is a cover function to fix_new_exp.
262 It exists because we record INSN with the fixup.
263
264 FRAG and WHERE are their respective arguments to fix_new_exp.
265 LENGTH is in bits.
266 OPINFO is something the caller chooses to help in reloc determination.
267
268 At this point we do not use a bfd_reloc_code_real_type for
269 operands residing in the insn, but instead just use the
270 operand index. This lets us easily handle fixups for any
271 operand type. We pick a BFD reloc type in md_apply_fix. */
272
273 fixS *
274 gas_cgen_record_fixup_exp (fragS *frag, int where, const CGEN_INSN *insn,
275 int length, const CGEN_OPERAND *operand, int opinfo,
276 expressionS *exp)
277 {
278 fixS *fixP;
279
280 /* It may seem strange to use operand->attrs and not insn->attrs here,
281 but it is the operand that has a pc relative relocation. */
282 fixP = fix_new_exp (frag, where, length / 8, exp,
283 CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
284 BFD_RELOC_UNUSED + operand->type);
285 fixP->fx_cgen.insn = insn;
286 fixP->fx_cgen.opinfo = opinfo;
287 fixP->fx_cgen.field = NULL;
288 fixP->fx_cgen.msb_field_p = 0;
289
290 return fixP;
291 }
292
293 #ifdef OBJ_COMPLEX_RELC
294 static symbolS *
295 expr_build_binary (operatorT op, symbolS * s1, symbolS * s2)
296 {
297 expressionS e;
298
299 e.X_op = op;
300 e.X_add_symbol = s1;
301 e.X_op_symbol = s2;
302 e.X_add_number = 0;
303 return make_expr_symbol (& e);
304 }
305 #endif
306
307 /* Used for communication between the next two procedures. */
308 static jmp_buf expr_jmp_buf;
309 static int expr_jmp_buf_p;
310
311 /* Callback for cgen interface. Parse the expression at *STRP.
312 The result is an error message or NULL for success (in which case
313 *STRP is advanced past the parsed text).
314 WANT is an indication of what the caller is looking for.
315 If WANT == CGEN_ASM_PARSE_INIT the caller is beginning to try to match
316 a table entry with the insn, reset the queued fixups counter.
317 An enum cgen_parse_operand_result is stored in RESULTP.
318 OPINDEX is the operand's table entry index.
319 OPINFO is something the caller chooses to help in reloc determination.
320 The resulting value is stored in VALUEP. */
321
322 const char *
323 gas_cgen_parse_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
324 enum cgen_parse_operand_type want, const char **strP,
325 int opindex, int opinfo,
326 enum cgen_parse_operand_result *resultP,
327 bfd_vma *valueP)
328 {
329 #ifdef __STDC__
330 /* These are volatile to survive the setjmp. */
331 char * volatile hold;
332 enum cgen_parse_operand_result * volatile resultP_1;
333 volatile int opinfo_1;
334 #else
335 static char *hold;
336 static enum cgen_parse_operand_result *resultP_1;
337 int opinfo_1;
338 #endif
339 const char *errmsg;
340 expressionS exp;
341
342 #ifdef OBJ_COMPLEX_RELC
343 volatile int signed_p = 0;
344 symbolS * stmp = NULL;
345 bfd_reloc_code_real_type reloc_type;
346 const CGEN_OPERAND * operand;
347 fixS dummy_fixup;
348 #endif
349 if (want == CGEN_PARSE_OPERAND_INIT)
350 {
351 gas_cgen_init_parse ();
352 return NULL;
353 }
354
355 resultP_1 = resultP;
356 hold = input_line_pointer;
357 input_line_pointer = (char *) *strP;
358 opinfo_1 = opinfo;
359
360 /* We rely on md_operand to longjmp back to us.
361 This is done via gas_cgen_md_operand. */
362 if (setjmp (expr_jmp_buf) != 0)
363 {
364 expr_jmp_buf_p = 0;
365 input_line_pointer = (char *) hold;
366 *resultP_1 = CGEN_PARSE_OPERAND_RESULT_ERROR;
367 return _("illegal operand");
368 }
369
370 expr_jmp_buf_p = 1;
371 expression (&exp);
372 expr_jmp_buf_p = 0;
373 errmsg = NULL;
374
375 *strP = input_line_pointer;
376 input_line_pointer = hold;
377
378 #ifdef TC_CGEN_PARSE_FIX_EXP
379 opinfo_1 = TC_CGEN_PARSE_FIX_EXP (opinfo_1, & exp);
380 #endif
381
382 /* FIXME: Need to check `want'. */
383
384 resolve_register (&exp);
385
386 switch (exp.X_op)
387 {
388 case O_illegal:
389 errmsg = _("illegal operand");
390 *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
391 break;
392 case O_absent:
393 errmsg = _("missing operand");
394 *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
395 break;
396 case O_constant:
397 if (want == CGEN_PARSE_OPERAND_SYMBOLIC)
398 goto de_fault;
399 *valueP = exp.X_add_number;
400 *resultP = CGEN_PARSE_OPERAND_RESULT_NUMBER;
401 break;
402 case O_register:
403 *valueP = exp.X_add_number;
404 *resultP = CGEN_PARSE_OPERAND_RESULT_REGISTER;
405 break;
406 de_fault:
407 default:
408 #ifdef OBJ_COMPLEX_RELC
409 /* Look up operand, check to see if there's an obvious
410 overflow (this helps disambiguate some insn parses). */
411 operand = cgen_operand_lookup_by_num (cd, opindex);
412 errmsg = weak_operand_overflow_check (& exp, operand);
413
414 if (! errmsg)
415 {
416 asymbol *bsym;
417
418 /* Fragment the expression as necessary, and queue a reloc. */
419 memset (& dummy_fixup, 0, sizeof (fixS));
420
421 reloc_type = md_cgen_lookup_reloc (0, operand, & dummy_fixup);
422
423 if (exp.X_op == O_symbol
424 && reloc_type == BFD_RELOC_RELC
425 && symbol_constant_p (exp.X_add_symbol)
426 && (!symbol_symbolS (exp.X_add_symbol)
427 || (bsym = symbol_get_bfdsym (exp.X_add_symbol)) == NULL
428 || (bsym->section != expr_section
429 && bsym->section != absolute_section
430 && bsym->section != undefined_section)))
431 {
432 /* Local labels will have been (eagerly) turned into constants
433 by now, due to the inappropriately deep insight of the
434 expression parser. Unfortunately make_expr_symbol
435 prematurely dives into the symbol evaluator, and in this
436 case it gets a bad answer, so we manually create the
437 expression symbol we want here. */
438 stmp = symbol_create (FAKE_LABEL_NAME, expr_section,
439 &zero_address_frag, 0);
440 symbol_set_value_expression (stmp, & exp);
441 }
442 else
443 stmp = make_expr_symbol (& exp);
444
445 /* If this is a pc-relative RELC operand, we
446 need to subtract "." from the expression. */
447 if (reloc_type == BFD_RELOC_RELC
448 && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR))
449 stmp = expr_build_binary (O_subtract, stmp, expr_build_dot ());
450
451 /* FIXME: this is not a perfect heuristic for figuring out
452 whether an operand is signed: it only works when the operand
453 is an immediate. it's not terribly likely that any other
454 values will be signed relocs, but it's possible. */
455 if (operand && (operand->hw_type == HW_H_SINT))
456 signed_p = 1;
457
458 if (symbol_symbolS (stmp)
459 && (bsym = symbol_get_bfdsym (stmp)) != NULL
460 && bsym->section == expr_section
461 && ! S_IS_LOCAL (stmp))
462 {
463 if (signed_p)
464 bsym->flags |= BSF_SRELC;
465 else
466 bsym->flags |= BSF_RELC;
467 }
468
469 /* Now package it all up for the fixup emitter. */
470 exp.X_op = O_symbol;
471 exp.X_op_symbol = 0;
472 exp.X_add_symbol = stmp;
473 exp.X_add_number = 0;
474
475 /* Re-init rightshift quantity, just in case. */
476 rightshift = operand->length;
477 queue_fixup_recursively (opindex, opinfo_1, & exp,
478 (reloc_type == BFD_RELOC_RELC
479 ? &operand->index_fields : 0),
480 signed_p, -1);
481 }
482 *resultP = (errmsg
483 ? CGEN_PARSE_OPERAND_RESULT_ERROR
484 : CGEN_PARSE_OPERAND_RESULT_QUEUED);
485 *valueP = 0;
486 #else
487 queue_fixup (opindex, opinfo_1, &exp);
488 *valueP = 0;
489 *resultP = CGEN_PARSE_OPERAND_RESULT_QUEUED;
490 #endif
491 break;
492 }
493
494 return errmsg;
495 }
496
497 /* md_operand handler to catch unrecognized expressions and halt the
498 parsing process so the next entry can be tried.
499
500 ??? This could be done differently by adding code to `expression'. */
501
502 void
503 gas_cgen_md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
504 {
505 /* Don't longjmp if we're not called from within cgen_parse_operand(). */
506 if (expr_jmp_buf_p)
507 longjmp (expr_jmp_buf, 1);
508 }
509
510 /* Finish assembling instruction INSN.
511 BUF contains what we've built up so far.
512 LENGTH is the size of the insn in bits.
513 RELAX_P is non-zero if relaxable insns should be emitted as such.
514 Otherwise they're emitted in non-relaxable forms.
515 The "result" is stored in RESULT if non-NULL. */
516
517 void
518 gas_cgen_finish_insn (const CGEN_INSN *insn, CGEN_INSN_BYTES_PTR buf,
519 unsigned int length, int relax_p, finished_insnS *result)
520 {
521 int i;
522 int relax_operand;
523 char *f;
524 unsigned int byte_len = length / 8;
525
526 /* ??? Target foo issues various warnings here, so one might want to provide
527 a hook here. However, our caller is defined in tc-foo.c so there
528 shouldn't be a need for a hook. */
529
530 /* Write out the instruction.
531 It is important to fetch enough space in one call to `frag_more'.
532 We use (f - frag_now->fr_literal) to compute where we are and we
533 don't want frag_now to change between calls.
534
535 Relaxable instructions: We need to ensure we allocate enough
536 space for the largest insn. */
537
538 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED))
539 /* These currently shouldn't get here. */
540 abort ();
541
542 /* Is there a relaxable insn with the relaxable operand needing a fixup? */
543
544 relax_operand = -1;
545 if (relax_p && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE))
546 {
547 /* Scan the fixups for the operand affected by relaxing
548 (i.e. the branch address). */
549
550 for (i = 0; i < num_fixups; ++i)
551 {
552 if (CGEN_OPERAND_ATTR_VALUE (cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex),
553 CGEN_OPERAND_RELAX))
554 {
555 relax_operand = i;
556 break;
557 }
558 }
559 }
560
561 if (relax_operand != -1)
562 {
563 int max_len;
564 fragS *old_frag;
565 expressionS *exp;
566 symbolS *sym;
567 offsetT off;
568
569 #ifdef TC_CGEN_MAX_RELAX
570 max_len = TC_CGEN_MAX_RELAX (insn, byte_len);
571 #else
572 max_len = CGEN_MAX_INSN_SIZE;
573 #endif
574 /* Ensure variable part and fixed part are in same fragment. */
575 /* FIXME: Having to do this seems like a hack. */
576 frag_grow (max_len);
577
578 /* Allocate space for the fixed part. */
579 f = frag_more (byte_len);
580
581 /* Create a relaxable fragment for this instruction. */
582 old_frag = frag_now;
583
584 exp = &fixups[relax_operand].exp;
585 sym = exp->X_add_symbol;
586 off = exp->X_add_number;
587 if (exp->X_op != O_constant && exp->X_op != O_symbol)
588 {
589 /* Handle complex expressions. */
590 sym = make_expr_symbol (exp);
591 off = 0;
592 }
593
594 frag_var (rs_machine_dependent,
595 max_len - byte_len /* max chars */,
596 0 /* variable part already allocated */,
597 /* FIXME: When we machine generate the relax table,
598 machine generate a macro to compute subtype. */
599 1 /* subtype */,
600 sym,
601 off,
602 f);
603
604 /* Record the operand number with the fragment so md_convert_frag
605 can use gas_cgen_md_record_fixup to record the appropriate reloc. */
606 old_frag->fr_cgen.insn = insn;
607 old_frag->fr_cgen.opindex = fixups[relax_operand].opindex;
608 old_frag->fr_cgen.opinfo = fixups[relax_operand].opinfo;
609 if (result)
610 result->frag = old_frag;
611 }
612 else
613 {
614 f = frag_more (byte_len);
615 if (result)
616 result->frag = frag_now;
617 }
618
619 /* If we're recording insns as numbers (rather than a string of bytes),
620 target byte order handling is deferred until now. */
621 #if CGEN_INT_INSN_P
622 cgen_put_insn_value (gas_cgen_cpu_desc, (unsigned char *) f, length, *buf,
623 gas_cgen_cpu_desc->insn_endian);
624 #else
625 memcpy (f, buf, byte_len);
626 #endif
627
628 /* Emit DWARF2 debugging information. */
629 dwarf2_emit_insn (byte_len);
630
631 /* Create any fixups. */
632 for (i = 0; i < num_fixups; ++i)
633 {
634 fixS *fixP;
635 const CGEN_OPERAND *operand =
636 cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex);
637
638 /* Don't create fixups for these. That's done during relaxation.
639 We don't need to test for CGEN_INSN_RELAXED as they can't get here
640 (see above). */
641 if (relax_p
642 && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE)
643 && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_RELAX))
644 continue;
645
646 #ifndef md_cgen_record_fixup_exp
647 #define md_cgen_record_fixup_exp gas_cgen_record_fixup_exp
648 #endif
649
650 fixP = md_cgen_record_fixup_exp (frag_now, f - frag_now->fr_literal,
651 insn, length, operand,
652 fixups[i].opinfo,
653 &fixups[i].exp);
654 fixP->fx_cgen.field = fixups[i].field;
655 fixP->fx_cgen.msb_field_p = fixups[i].msb_field_p;
656 if (result)
657 result->fixups[i] = fixP;
658 }
659
660 if (result)
661 {
662 result->num_fixups = num_fixups;
663 result->addr = f;
664 }
665 }
666
667 #ifdef OBJ_COMPLEX_RELC
668 /* Queue many fixups, recursively. If the field is a multi-ifield,
669 repeatedly queue its sub-parts, right shifted to fit into the field (we
670 assume here multi-fields represent a left-to-right, MSB0-LSB0
671 reading). */
672
673 static void
674 queue_fixup_recursively (const int opindex,
675 const int opinfo,
676 expressionS * expP,
677 const CGEN_MAYBE_MULTI_IFLD * field,
678 const int signed_p,
679 const int part_of_multi)
680 {
681 if (field && field->count)
682 {
683 int i;
684
685 for (i = 0; i < field->count; ++ i)
686 queue_fixup_recursively (opindex, opinfo, expP,
687 & (field->val.multi[i]), signed_p, i);
688 }
689 else
690 {
691 expressionS * new_exp = expP;
692
693 #ifdef DEBUG
694 printf ("queueing fixup for field %s\n",
695 (field ? field->val.leaf->name : "??"));
696 print_symbol_value (expP->X_add_symbol);
697 #endif
698 if (field && part_of_multi != -1)
699 {
700 rightshift -= field->val.leaf->length;
701
702 /* Shift reloc value by number of bits remaining after this
703 field. */
704 if (rightshift)
705 new_exp = make_right_shifted_expr (expP, rightshift, signed_p);
706 }
707
708 /* Truncate reloc values to length, *after* leftmost one. */
709 fixups[num_fixups].msb_field_p = (part_of_multi <= 0);
710 fixups[num_fixups].field = (CGEN_MAYBE_MULTI_IFLD *) field;
711
712 queue_fixup (opindex, opinfo, new_exp);
713 }
714 }
715
716 /* Encode the self-describing RELC reloc format's addend. */
717
718 static unsigned long
719 gas_cgen_encode_addend (const unsigned long start, /* in bits */
720 const unsigned long len, /* in bits */
721 const unsigned long oplen, /* in bits */
722 const unsigned long wordsz, /* in bytes */
723 const unsigned long chunksz, /* in bytes */
724 const unsigned long signed_p,
725 const unsigned long trunc_p)
726 {
727 unsigned long res = 0L;
728
729 res |= start & 0x3F;
730 res |= (oplen & 0x3F) << 6;
731 res |= (len & 0x3F) << 12;
732 res |= (wordsz & 0xF) << 18;
733 res |= (chunksz & 0xF) << 22;
734 res |= (CGEN_INSN_LSB0_P ? 1 : 0) << 27;
735 res |= signed_p << 28;
736 res |= trunc_p << 29;
737
738 return res;
739 }
740
741 /* Purpose: make a weak check that the expression doesn't overflow the
742 operand it's to be inserted into.
743
744 Rationale: some insns used to use %operators to disambiguate during a
745 parse. when these %operators are translated to expressions by the macro
746 expander, the ambiguity returns. we attempt to disambiguate by field
747 size.
748
749 Method: check to see if the expression's top node is an O_and operator,
750 and the mask is larger than the operand length. This would be an
751 overflow, so signal it by returning an error string. Any other case is
752 ambiguous, so we assume it's OK and return NULL. */
753
754 static const char *
755 weak_operand_overflow_check (const expressionS * exp,
756 const CGEN_OPERAND * operand)
757 {
758 const unsigned long len = operand->length;
759 unsigned long mask;
760 unsigned long opmask = len == 0 ? 0 : (1UL << (len - 1) << 1) - 1;
761
762 if (!exp)
763 return NULL;
764
765 if (exp->X_op != O_bit_and)
766 {
767 /* Check for implicit overflow flag. */
768 if (CGEN_OPERAND_ATTR_VALUE
769 (operand, CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW))
770 return _("a reloc on this operand implies an overflow");
771 return NULL;
772 }
773
774 mask = exp->X_add_number;
775
776 if (exp->X_add_symbol
777 && symbol_constant_p (exp->X_add_symbol))
778 mask |= *symbol_X_add_number (exp->X_add_symbol);
779
780 if (exp->X_op_symbol
781 && symbol_constant_p (exp->X_op_symbol))
782 mask |= *symbol_X_add_number (exp->X_op_symbol);
783
784 /* Want to know if mask covers more bits than opmask.
785 this is the same as asking if mask has any bits not in opmask,
786 or whether (mask & ~opmask) is nonzero. */
787 if (mask && (mask & ~opmask))
788 {
789 #ifdef DEBUG
790 printf ("overflow: (mask = %8.8x, ~opmask = %8.8x, AND = %8.8x)\n",
791 mask, ~opmask, (mask & ~opmask));
792 #endif
793 return _("operand mask overflow");
794 }
795
796 return NULL;
797 }
798
799 static expressionS *
800 make_right_shifted_expr (expressionS * exp,
801 const int amount,
802 const int signed_p)
803 {
804 symbolS * stmp = 0;
805 expressionS * new_exp;
806 asymbol *bsym;
807
808 stmp = expr_build_binary (O_right_shift,
809 make_expr_symbol (exp),
810 expr_build_uconstant (amount));
811 bsym = symbol_get_bfdsym (stmp);
812
813 if (signed_p)
814 bsym->flags |= BSF_SRELC;
815 else
816 bsym->flags |= BSF_RELC;
817
818 /* Then wrap that in a "symbol expr" for good measure. */
819 new_exp = XNEW (expressionS);
820 memset (new_exp, 0, sizeof (expressionS));
821 new_exp->X_op = O_symbol;
822 new_exp->X_op_symbol = 0;
823 new_exp->X_add_symbol = stmp;
824 new_exp->X_add_number = 0;
825
826 return new_exp;
827 }
828
829 #endif
830
831 /* Apply a fixup to the object code. This is called for all the
832 fixups we generated by the call to fix_new_exp, above. In the call
833 above we used a reloc code which was the largest legal reloc code
834 plus the operand index. Here we undo that to recover the operand
835 index. At this point all symbol values should be fully resolved,
836 and we attempt to completely resolve the reloc. If we can not do
837 that, we determine the correct reloc code and put it back in the fixup. */
838
839 /* FIXME: This function handles some of the fixups and bfd_install_relocation
840 handles the rest. bfd_install_relocation (or some other bfd function)
841 should handle them all. */
842
843 void
844 gas_cgen_md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
845 {
846 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
847 valueT value = * valP;
848 /* Canonical name, since used a lot. */
849 CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
850
851 if (fixP->fx_addsy == NULL)
852 fixP->fx_done = 1;
853
854 /* We don't actually support subtracting a symbol. */
855 if (fixP->fx_subsy != NULL)
856 as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
857
858 if (fixP->fx_r_type >= BFD_RELOC_UNUSED)
859 {
860 int opindex = fixP->fx_r_type - BFD_RELOC_UNUSED;
861 const CGEN_OPERAND *operand = cgen_operand_lookup_by_num (cd, opindex);
862 const char *errmsg;
863 bfd_reloc_code_real_type reloc_type;
864 const CGEN_INSN *insn = fixP->fx_cgen.insn;
865 #ifdef OBJ_COMPLEX_RELC
866 int start;
867 int length;
868 int signed_p = 0;
869
870 if (fixP->fx_cgen.field)
871 {
872 /* Use the twisty little pointer path
873 back to the ifield if it exists. */
874 start = fixP->fx_cgen.field->val.leaf->start;
875 length = fixP->fx_cgen.field->val.leaf->length;
876 }
877 else
878 {
879 /* Or the far less useful operand-size guesstimate. */
880 start = operand->start;
881 length = operand->length;
882 }
883
884 /* FIXME: this is not a perfect heuristic for figuring out
885 whether an operand is signed: it only works when the operand
886 is an immediate. it's not terribly likely that any other
887 values will be signed relocs, but it's possible. */
888 if (operand && (operand->hw_type == HW_H_SINT))
889 signed_p = 1;
890 #endif
891
892 /* If the reloc has been fully resolved finish the operand here. */
893 /* FIXME: This duplicates the capabilities of code in BFD. */
894 if (fixP->fx_done
895 /* FIXME: If partial_inplace isn't set bfd_install_relocation won't
896 finish the job. Testing for pcrel is a temporary hack. */
897 || fixP->fx_pcrel)
898 {
899 CGEN_FIELDS *fields = xmalloc (CGEN_CPU_SIZEOF_FIELDS (cd));
900
901 CGEN_CPU_SET_FIELDS_BITSIZE (cd) (fields, CGEN_INSN_BITSIZE (insn));
902 CGEN_CPU_SET_VMA_OPERAND (cd) (cd, opindex, fields, (bfd_vma) value);
903
904 #if CGEN_INT_INSN_P
905 {
906 CGEN_INSN_INT insn_value =
907 cgen_get_insn_value (cd, (unsigned char *) where,
908 CGEN_INSN_BITSIZE (insn),
909 cd->insn_endian);
910
911 /* ??? 0 is passed for `pc'. */
912 errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
913 &insn_value, 0);
914 cgen_put_insn_value (cd, (unsigned char *) where,
915 CGEN_INSN_BITSIZE (insn), insn_value,
916 cd->insn_endian);
917 }
918 #else
919 /* ??? 0 is passed for `pc'. */
920 errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
921 (unsigned char *) where, 0);
922 #endif
923 if (errmsg)
924 as_bad_where (fixP->fx_file, fixP->fx_line, "%s", errmsg);
925
926 free (fields);
927 }
928
929 if (fixP->fx_done)
930 return;
931
932 /* The operand isn't fully resolved. Determine a BFD reloc value
933 based on the operand information and leave it to
934 bfd_install_relocation. Note that this doesn't work when
935 partial_inplace == false. */
936
937 reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
938 #ifdef OBJ_COMPLEX_RELC
939 if (reloc_type == BFD_RELOC_RELC)
940 {
941 /* Change addend to "self-describing" form,
942 for BFD to handle in the linker. */
943 value = gas_cgen_encode_addend (start, operand->length,
944 length, fixP->fx_size,
945 cd->insn_chunk_bitsize / 8,
946 signed_p,
947 ! (fixP->fx_cgen.msb_field_p));
948 }
949 #endif
950
951 if (reloc_type != BFD_RELOC_NONE)
952 fixP->fx_r_type = reloc_type;
953 else
954 {
955 as_bad_where (fixP->fx_file, fixP->fx_line,
956 _("unresolved expression that must be resolved"));
957 fixP->fx_done = 1;
958 return;
959 }
960 }
961 else if (fixP->fx_done)
962 {
963 /* We're finished with this fixup. Install it because
964 bfd_install_relocation won't be called to do it. */
965 switch (fixP->fx_r_type)
966 {
967 case BFD_RELOC_8:
968 md_number_to_chars (where, value, 1);
969 break;
970 case BFD_RELOC_16:
971 md_number_to_chars (where, value, 2);
972 break;
973 case BFD_RELOC_32:
974 md_number_to_chars (where, value, 4);
975 break;
976 case BFD_RELOC_64:
977 md_number_to_chars (where, value, 8);
978 break;
979 default:
980 as_bad_where (fixP->fx_file, fixP->fx_line,
981 _("internal error: can't install fix for reloc type %d (`%s')"),
982 fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
983 break;
984 }
985 }
986 /* else
987 bfd_install_relocation will be called to finish things up. */
988
989 /* Tuck `value' away for use by tc_gen_reloc.
990 See the comment describing fx_addnumber in write.h.
991 This field is misnamed (or misused :-). */
992 fixP->fx_addnumber = value;
993 }
994
995 bfd_reloc_code_real_type
996 gas_cgen_pcrel_r_type (bfd_reloc_code_real_type r)
997 {
998 switch (r)
999 {
1000 case BFD_RELOC_8: r = BFD_RELOC_8_PCREL; break;
1001 case BFD_RELOC_16: r = BFD_RELOC_16_PCREL; break;
1002 case BFD_RELOC_24: r = BFD_RELOC_24_PCREL; break;
1003 case BFD_RELOC_32: r = BFD_RELOC_32_PCREL; break;
1004 case BFD_RELOC_64: r = BFD_RELOC_64_PCREL; break;
1005 default:
1006 break;
1007 }
1008 return r;
1009 }
1010
1011 /* Translate internal representation of relocation info to BFD target format.
1012
1013 FIXME: To what extent can we get all relevant targets to use this? */
1014
1015 arelent *
1016 gas_cgen_tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
1017 {
1018 bfd_reloc_code_real_type r_type = fixP->fx_r_type;
1019 arelent *reloc;
1020
1021 reloc = notes_alloc (sizeof (arelent));
1022 reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
1023 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1024
1025 #ifdef GAS_CGEN_PCREL_R_TYPE
1026 if (fixP->fx_pcrel)
1027 r_type = GAS_CGEN_PCREL_R_TYPE (r_type);
1028 #endif
1029 reloc->howto = bfd_reloc_type_lookup (stdoutput, r_type);
1030
1031 if (reloc->howto == NULL)
1032 {
1033 as_bad_where (fixP->fx_file, fixP->fx_line,
1034 _("relocation is not supported"));
1035 return NULL;
1036 }
1037
1038 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1039
1040 /* Use fx_offset for these cases. */
1041 if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
1042 || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
1043 reloc->addend = fixP->fx_offset;
1044 else
1045 reloc->addend = fixP->fx_addnumber;
1046
1047 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1048 return reloc;
1049 }
1050
1051 /* Perform any cgen specific initialisation.
1052 Called after gas_cgen_cpu_desc has been created. */
1053
1054 void
1055 gas_cgen_begin (void)
1056 {
1057 if (flag_signed_overflow_ok)
1058 cgen_set_signed_overflow_ok (gas_cgen_cpu_desc);
1059 else
1060 cgen_clear_signed_overflow_ok (gas_cgen_cpu_desc);
1061 }
1062