Coverage Report

Created: 2025-06-24 06:45

/src/binutils-gdb/bfd/elf32-d30v.c
Line
Count
Source (jump to first uncovered line)
1
/* D30V-specific support for 32-bit ELF
2
   Copyright (C) 1997-2025 Free Software Foundation, Inc.
3
   Contributed by Martin Hunt (hunt@cygnus.com).
4
5
   This file is part of BFD, the Binary File Descriptor library.
6
7
   This program 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 3 of the License, or
10
   (at your option) any later version.
11
12
   This program 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 this program; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
22
#include "sysdep.h"
23
#include "bfd.h"
24
#include "libbfd.h"
25
#include "elf-bfd.h"
26
#include "elf/d30v.h"
27
28
0
#define MAX32 ((bfd_signed_vma) 0x7fffffff)
29
0
#define MIN32 (- MAX32 - 1)
30
31
static bfd_reloc_status_type
32
bfd_elf_d30v_reloc (bfd *abfd,
33
        arelent *reloc_entry,
34
        asymbol *symbol,
35
        void * data,
36
        asection *input_section,
37
        bfd *output_bfd,
38
        char **error_message)
39
0
{
40
0
  bfd_signed_vma relocation;
41
0
  bfd_vma in1, in2, num;
42
0
  bfd_vma tmp_addr = 0;
43
0
  bfd_reloc_status_type r;
44
0
  asection *reloc_target_output_section;
45
0
  bfd_size_type addr = reloc_entry->address;
46
0
  bfd_reloc_status_type flag = bfd_reloc_ok;
47
0
  bfd_vma output_base = 0;
48
0
  reloc_howto_type *howto = reloc_entry->howto;
49
0
  int make_absolute = 0;
50
51
0
  if (output_bfd != NULL)
52
0
    {
53
      /* Partial linking -- do nothing.  */
54
0
      reloc_entry->address += input_section->output_offset;
55
0
      return bfd_reloc_ok;
56
0
    }
57
58
0
  r = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
59
0
           input_section, output_bfd, error_message);
60
0
  if (r != bfd_reloc_continue)
61
0
    return r;
62
63
  /* A hacked-up version of bfd_perform_reloc() follows.  */
64
0
 if (bfd_is_und_section (symbol->section)
65
0
      && (symbol->flags & BSF_WEAK) == 0
66
0
      && output_bfd == NULL)
67
0
    flag = bfd_reloc_undefined;
68
69
  /* Is the address of the relocation really within the section?  */
70
0
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
71
0
    return bfd_reloc_outofrange;
72
73
  /* Work out which section the relocation is targeted at and the
74
     initial relocation command value.  */
75
76
  /* Get symbol value.  (Common symbols are special.)  */
77
0
  if (bfd_is_com_section (symbol->section))
78
0
    relocation = 0;
79
0
  else
80
0
    relocation = symbol->value;
81
82
0
  reloc_target_output_section = symbol->section->output_section;
83
84
  /* Convert input-section-relative symbol value to absolute.  */
85
0
  output_base = reloc_target_output_section->vma;
86
0
  relocation += output_base + symbol->section->output_offset;
87
88
  /* Add in supplied addend.  */
89
0
  relocation += reloc_entry->addend;
90
91
  /* Here the variable relocation holds the final address of the
92
     symbol we are relocating against, plus any addend.  */
93
0
  if (howto->pc_relative)
94
0
    {
95
0
      tmp_addr = input_section->output_section->vma
96
0
  + input_section->output_offset
97
0
  + reloc_entry->address;
98
0
      relocation -= tmp_addr;
99
0
    }
100
101
0
  in1 = bfd_get_32 (abfd, (bfd_byte *) data + addr);
102
0
  in2 = bfd_get_32 (abfd, (bfd_byte *) data + addr + 4);
103
104
  /* Extract the addend.  */
105
0
  num = ((in2 & 0x3FFFF)
106
0
   | ((in2 & 0xFF00000) >> 2)
107
0
   | ((in1 & 0x3F) << 26));
108
0
  in1 &= 0xFFFFFFC0;
109
0
  in2 = 0x80000000;
110
111
0
  relocation += num;
112
113
0
  if (howto->pc_relative && howto->bitsize == 32)
114
0
    {
115
      /* The D30V has a PC that doesn't wrap and PC-relative jumps are
116
   signed, so a PC-relative jump can't be more than +/- 2^31 bytes.
117
   If one exceeds this, change it to an absolute jump.  */
118
0
      if (relocation > MAX32 || relocation < MIN32)
119
0
  {
120
0
    relocation = (relocation + tmp_addr) & 0xffffffff;
121
0
    make_absolute = 1;
122
0
  }
123
0
    }
124
125
0
  in1 |= (relocation >> 26) & 0x3F;   /* Top 6 bits.  */
126
0
  in2 |= ((relocation & 0x03FC0000) << 2);  /* Next 8 bits.  */
127
0
  in2 |= relocation & 0x0003FFFF;   /* Bottom 18 bits.  */
128
129
  /* Change a PC-relative instruction to its
130
     absolute equivalent with this simple hack.  */
131
0
  if (make_absolute)
132
0
    in1 |= 0x00100000;
133
134
0
  bfd_put_32 (abfd, in1, (bfd_byte *) data + addr);
135
0
  bfd_put_32 (abfd, in2, (bfd_byte *) data + addr + 4);
136
137
0
  return flag;
138
0
}
139
140
static bfd_reloc_status_type
141
bfd_elf_d30v_reloc_21 (bfd *abfd,
142
           arelent *reloc_entry,
143
           asymbol *symbol,
144
           void * data,
145
           asection *input_section,
146
           bfd *output_bfd,
147
           char **error_message)
148
0
{
149
0
  bfd_vma relocation;
150
0
  bfd_vma in1, num;
151
0
  bfd_reloc_status_type r;
152
0
  asection *reloc_target_output_section;
153
0
  bfd_size_type addr = reloc_entry->address;
154
0
  bfd_reloc_status_type flag = bfd_reloc_ok;
155
0
  bfd_vma output_base = 0;
156
0
  reloc_howto_type *howto = reloc_entry->howto;
157
0
  int mask, max;
158
159
0
  if (output_bfd != NULL)
160
0
    {
161
      /* Partial linking -- do nothing.  */
162
0
      reloc_entry->address += input_section->output_offset;
163
0
      return bfd_reloc_ok;
164
0
    }
165
166
0
  r = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
167
0
           input_section, output_bfd, error_message);
168
0
  if (r != bfd_reloc_continue)
169
0
    return r;
170
171
  /* A hacked-up version of bfd_perform_reloc() follows.  */
172
0
  if (bfd_is_und_section (symbol->section)
173
0
      && (symbol->flags & BSF_WEAK) == 0
174
0
      && output_bfd == NULL)
175
0
    flag = bfd_reloc_undefined;
176
177
  /* Is the address of the relocation really within the section?  */
178
0
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
179
0
    return bfd_reloc_outofrange;
180
181
  /* Work out which section the relocation is targeted at and the
182
     initial relocation command value.  */
183
184
  /* Get symbol value.  (Common symbols are special.)  */
185
0
  if (bfd_is_com_section (symbol->section))
186
0
    relocation = 0;
187
0
  else
188
0
    relocation = symbol->value;
189
190
0
  reloc_target_output_section = symbol->section->output_section;
191
192
  /* Convert input-section-relative symbol value to absolute.  */
193
0
  output_base = reloc_target_output_section->vma;
194
0
  relocation += output_base + symbol->section->output_offset;
195
196
  /* Add in supplied addend.  */
197
0
  relocation += reloc_entry->addend;
198
199
  /* Here the variable relocation holds the final address of the
200
     symbol we are relocating against, plus any addend.  */
201
202
0
  if (howto->pc_relative)
203
0
    {
204
0
      relocation -= (input_section->output_section->vma
205
0
         + input_section->output_offset);
206
0
      if (howto->pcrel_offset)
207
0
  relocation -= reloc_entry->address;
208
0
    }
209
210
0
  in1 = bfd_get_32 (abfd, (bfd_byte *) data + addr);
211
212
0
  mask =  (1 << howto->bitsize) - 1;
213
0
  if (howto->bitsize == 6)
214
0
    mask <<= 12;
215
0
  max = (1 << (howto->bitsize + 2)) - 1;
216
217
  /* Extract the addend.  */
218
0
  num = in1 & mask;  /* 18 bits.  */
219
0
  if (howto->bitsize == 6)
220
0
    num >>= 12;
221
0
  num <<= 3; /* shift left 3.  */
222
0
  in1 &= ~mask;  /* Mask out addend.  */
223
224
0
  relocation += num;
225
0
  if (howto->type == R_D30V_21_PCREL_R
226
0
      || howto->type == R_D30V_15_PCREL_R
227
0
      || howto->type == R_D30V_9_PCREL_R)
228
0
    relocation += 4;
229
230
0
  if ((int) relocation < 0)
231
0
    {
232
0
      if (~ (int) relocation > max)
233
0
  flag = bfd_reloc_overflow;
234
0
    }
235
0
  else
236
0
    {
237
0
      if ((int) relocation > max)
238
0
  flag = bfd_reloc_overflow;
239
0
    }
240
241
0
  relocation >>= 3;
242
0
  if (howto->bitsize == 6)
243
0
    in1 |= ((relocation & (mask >> 12)) << 12);
244
0
  else
245
0
    in1 |= relocation & mask;
246
247
0
  bfd_put_32 (abfd, in1, (bfd_byte *) data + addr);
248
249
0
  return flag;
250
0
}
251
252
static reloc_howto_type elf_d30v_howto_table[] =
253
{
254
  /* This reloc does nothing.  */
255
  HOWTO (R_D30V_NONE,   /* Type.  */
256
   0,     /* Rightshift.  */
257
   0,     /* Size.  */
258
   0,     /* Bitsize.  */
259
   false,     /* PC_relative.  */
260
   0,     /* Bitpos.  */
261
   complain_overflow_dont, /* Complain_on_overflow.  */
262
   bfd_elf_generic_reloc, /* Special_function.  */
263
   "R_D30V_NONE",   /* Name.  */
264
   false,     /* Partial_inplace.  */
265
   0,     /* Src_mask.  */
266
   0,     /* Dst_mask.  */
267
   false),    /* PCrel_offset.  */
268
269
  /* A 6 bit absolute relocation.  */
270
  HOWTO (R_D30V_6,    /* Type.  */
271
   0,     /* Rightshift.  */
272
   4,     /* Size.  */
273
   6,     /* Bitsize.  */
274
   false,     /* PC_relative.  */
275
   0,     /* Bitpos.  */
276
   complain_overflow_bitfield, /* Complain_on_overflow.  */
277
   bfd_elf_generic_reloc, /* Special_function.  */
278
   "R_D30V_6",    /* Name.  */
279
   false,     /* Partial_inplace.  */
280
   0x3f,      /* Src_mask.  */
281
   0x3f,      /* Dst_mask.  */
282
   false),    /* PCrel_offset.  */
283
284
  /* A relative 9 bit relocation, right shifted by 3.  */
285
  HOWTO (R_D30V_9_PCREL,  /* Type.  */
286
   3,     /* Rightshift.  */
287
   4,     /* Size.  */
288
   6,     /* Bitsize.  */
289
   true,      /* PC_relative.  */
290
   0,     /* Bitpos.  */
291
   complain_overflow_signed, /* Complain_on_overflow.  */
292
   bfd_elf_d30v_reloc_21, /* Special_function.  */
293
   "R_D30V_9_PCREL",  /* Name.  */
294
   false,     /* Partial_inplace.  */
295
   0x3f,      /* Src_mask.  */
296
   0x3f,      /* Dst_mask.  */
297
   true),     /* PCrel_offset.  */
298
299
  /* A relative 9 bit relocation, right shifted by 3.  */
300
  HOWTO (R_D30V_9_PCREL_R,  /* Type.  */
301
   3,     /* Rightshift.  */
302
   4,     /* Size.  */
303
   6,     /* Bitsize.  */
304
   true,      /* PC_relative.  */
305
   0,     /* Bitpos.  */
306
   complain_overflow_signed, /* Complain_on_overflow.  */
307
   bfd_elf_d30v_reloc_21, /* Special_function.  */
308
   "R_D30V_9_PCREL_R",  /* Name.  */
309
   false,     /* Partial_inplace.  */
310
   0x3f,      /* Src_mask.  */
311
   0x3f,      /* Dst_mask.  */
312
   true),     /* PCrel_offset.  */
313
314
  /* An absolute 15 bit relocation, right shifted by 3.  */
315
  HOWTO (R_D30V_15,   /* Type.  */
316
   3,     /* Rightshift.  */
317
   4,     /* Size.  */
318
   12,      /* Bitsize.  */
319
   false,     /* PC_relative.  */
320
   0,     /* Bitpos.  */
321
   complain_overflow_signed, /* Complain_on_overflow.  */
322
   bfd_elf_generic_reloc, /* Special_function.  */
323
   "R_D30V_15",   /* Name.  */
324
   false,     /* Partial_inplace.  */
325
   0xfff,     /* Src_mask.  */
326
   0xfff,     /* Dst_mask.  */
327
   false),    /* PCrel_offset.  */
328
329
  /* A relative 15 bit relocation, right shifted by 3.  */
330
  HOWTO (R_D30V_15_PCREL, /* Type.  */
331
   3,     /* Rightshift.  */
332
   4,     /* Size.  */
333
   12,      /* Bitsize.  */
334
   true,      /* PC_relative.  */
335
   0,     /* Bitpos.  */
336
   complain_overflow_signed, /* Complain_on_overflow.  */
337
   bfd_elf_d30v_reloc_21, /* Special_function.  */
338
   "R_D30V_15_PCREL", /* Name.  */
339
   false,     /* Partial_inplace.  */
340
   0xfff,     /* Src_mask.  */
341
   0xfff,     /* Dst_mask.  */
342
   true),     /* PCrel_offset.  */
343
344
  /* A relative 15 bit relocation, right shifted by 3.  */
345
  HOWTO (R_D30V_15_PCREL_R, /* Type.  */
346
   3,     /* Rightshift.  */
347
   4,     /* Size.  */
348
   12,      /* Bitsize.  */
349
   true,      /* PC_relative.  */
350
   0,     /* Bitpos.  */
351
   complain_overflow_signed, /* Complain_on_overflow.  */
352
   bfd_elf_d30v_reloc_21, /* Special_function.  */
353
   "R_D30V_15_PCREL_R", /* Name.  */
354
   false,     /* Partial_inplace.  */
355
   0xfff,     /* Src_mask.  */
356
   0xfff,     /* Dst_mask.  */
357
   true),     /* PCrel_offset.  */
358
359
  /* An absolute 21 bit relocation, right shifted by 3.  */
360
  HOWTO (R_D30V_21,   /* Type.  */
361
   3,     /* Rightshift.  */
362
   4,     /* Size.  */
363
   18,      /* Bitsize.  */
364
   false,     /* PC_relative.  */
365
   0,     /* Bitpos.  */
366
   complain_overflow_signed, /* Complain_on_overflow.  */
367
   bfd_elf_generic_reloc, /* Special_function.  */
368
   "R_D30V_21",   /* Name.  */
369
   false,     /* Partial_inplace.  */
370
   0x3ffff,   /* Src_mask.  */
371
   0x3ffff,   /* Dst_mask.  */
372
   false),    /* PCrel_offset.  */
373
374
  /* A relative 21 bit relocation, right shifted by 3.  */
375
  HOWTO (R_D30V_21_PCREL, /* Type.  */
376
   3,     /* Rightshift.  */
377
   4,     /* Size.  */
378
   18,      /* Bitsize.  */
379
   true,      /* PC_relative.  */
380
   0,     /* Bitpos.  */
381
   complain_overflow_signed, /* Complain_on_overflow.  */
382
   bfd_elf_d30v_reloc_21, /* Special_function.  */
383
   "R_D30V_21_PCREL", /* Name.  */
384
   false,     /* Partial_inplace.  */
385
   0x3ffff,   /* Src_mask.  */
386
   0x3ffff,   /* Dst_mask.  */
387
   true),     /* PCrel_offset.  */
388
389
  /* A relative 21 bit relocation, right shifted by 3, in the Right container.  */
390
  HOWTO (R_D30V_21_PCREL_R, /* Type.  */
391
   3,     /* Rightshift.  */
392
   4,     /* Size.  */
393
   18,      /* Bitsize.  */
394
   true,      /* PC_relative.  */
395
   0,     /* Bitpos.  */
396
   complain_overflow_signed, /* Complain_on_overflow.  */
397
   bfd_elf_d30v_reloc_21, /* Special_function.  */
398
   "R_D30V_21_PCREL_R", /* Name.  */
399
   false,     /* Partial_inplace.  */
400
   0x3ffff,   /* Src_mask.  */
401
   0x3ffff,   /* Dst_mask.  */
402
   true),     /* PCrel_offset.  */
403
404
  /* A D30V 32 bit absolute relocation.  */
405
  HOWTO (R_D30V_32,   /* Type.  */
406
   0,     /* Rightshift.  */
407
   8,     /* Size.  */
408
   32,      /* Bitsize.  */
409
   false,     /* PC_relative.  */
410
   0,     /* Bitpos.  */
411
   complain_overflow_bitfield, /* Complain_on_overflow.  */
412
   bfd_elf_d30v_reloc,  /* Special_function.  */
413
   "R_D30V_32",   /* Name.  */
414
   false,     /* Partial_inplace.  */
415
   0xffffffff,    /* Src_mask.  */
416
   0xffffffff,    /* Dst_mask.  */
417
   false),    /* PCrel_offset.  */
418
419
  /* A relative 32 bit relocation.  */
420
  HOWTO (R_D30V_32_PCREL, /* Type.  */
421
   0,     /* Rightshift.  */
422
   8,     /* Size.  */
423
   32,      /* Bitsize.  */
424
   true,      /* PC_relative.  */
425
   0,     /* Bitpos.  */
426
   complain_overflow_signed, /* Complain_on_overflow.  */
427
   bfd_elf_d30v_reloc,  /* Special_function.  */
428
   "R_D30V_32_PCREL", /* Name.  */
429
   false,     /* Partial_inplace.  */
430
   0xffffffff,    /* Src_mask.  */
431
   0xffffffff,    /* Dst_mask.  */
432
   true),     /* PCrel_offset.  */
433
434
  /* A regular 32 bit absolute relocation.  */
435
  HOWTO (R_D30V_32_NORMAL,  /* Type.  */
436
   0,     /* Rightshift.  */
437
   4,     /* Size.  */
438
   32,      /* Bitsize.  */
439
   false,     /* PC_relative.  */
440
   0,     /* Bitpos.  */
441
   complain_overflow_bitfield, /* Complain_on_overflow.  */
442
   bfd_elf_generic_reloc, /* Special_function.  */
443
   "R_D30V_32_NORMAL",  /* Name.  */
444
   false,     /* Partial_inplace.  */
445
   0xffffffff,    /* Src_mask.  */
446
   0xffffffff,    /* Dst_mask.  */
447
   false),    /* PCrel_offset.  */
448
449
};
450
451
/* Map BFD reloc types to D30V ELF reloc types.  */
452
453
struct d30v_reloc_map
454
{
455
  bfd_reloc_code_real_type bfd_reloc_val;
456
  unsigned char elf_reloc_val;
457
};
458
459
static const struct d30v_reloc_map d30v_reloc_map[] =
460
{
461
  { BFD_RELOC_NONE, R_D30V_NONE, },
462
  { BFD_RELOC_D30V_6, R_D30V_6 },
463
  { BFD_RELOC_D30V_9_PCREL, R_D30V_9_PCREL },
464
  { BFD_RELOC_D30V_9_PCREL_R, R_D30V_9_PCREL_R },
465
  { BFD_RELOC_D30V_15, R_D30V_15 },
466
  { BFD_RELOC_D30V_15_PCREL, R_D30V_15_PCREL },
467
  { BFD_RELOC_D30V_15_PCREL_R, R_D30V_15_PCREL_R },
468
  { BFD_RELOC_D30V_21, R_D30V_21 },
469
  { BFD_RELOC_D30V_21_PCREL, R_D30V_21_PCREL },
470
  { BFD_RELOC_D30V_21_PCREL_R, R_D30V_21_PCREL_R },
471
  { BFD_RELOC_D30V_32, R_D30V_32 },
472
  { BFD_RELOC_D30V_32_PCREL, R_D30V_32_PCREL },
473
  { BFD_RELOC_32, R_D30V_32_NORMAL },
474
};
475
476
static reloc_howto_type *
477
bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
478
         bfd_reloc_code_real_type code)
479
0
{
480
0
  unsigned int i;
481
482
0
  for (i = 0;
483
0
       i < sizeof (d30v_reloc_map) / sizeof (struct d30v_reloc_map);
484
0
       i++)
485
0
    {
486
0
      if (d30v_reloc_map[i].bfd_reloc_val == code)
487
0
  return &elf_d30v_howto_table[d30v_reloc_map[i].elf_reloc_val];
488
0
    }
489
490
0
  return NULL;
491
0
}
492
493
static reloc_howto_type *
494
bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
495
         const char *r_name)
496
0
{
497
0
  unsigned int i;
498
499
0
  for (i = 0;
500
0
       i < sizeof (elf_d30v_howto_table) / sizeof (elf_d30v_howto_table[0]);
501
0
       i++)
502
0
    if (elf_d30v_howto_table[i].name != NULL
503
0
  && strcasecmp (elf_d30v_howto_table[i].name, r_name) == 0)
504
0
      return &elf_d30v_howto_table[i];
505
506
0
  return NULL;
507
0
}
508
509
/* Set the howto pointer for an D30V ELF reloc (type REL).  */
510
511
static bool
512
d30v_info_to_howto_rel (bfd *abfd,
513
      arelent *cache_ptr,
514
      Elf_Internal_Rela *dst)
515
0
{
516
0
  unsigned int r_type;
517
518
0
  r_type = ELF32_R_TYPE (dst->r_info);
519
0
  if (r_type >= (unsigned int) R_D30V_max)
520
0
    {
521
      /* xgettext:c-format */
522
0
      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
523
0
        abfd, r_type);
524
0
      bfd_set_error (bfd_error_bad_value);
525
0
      return false;
526
0
    }
527
0
  cache_ptr->howto = &elf_d30v_howto_table[r_type];
528
0
  return true;
529
0
}
530
531
/* Set the howto pointer for an D30V ELF reloc (type RELA).  */
532
533
static bool
534
d30v_info_to_howto_rela (bfd *abfd,
535
       arelent *cache_ptr,
536
       Elf_Internal_Rela *dst)
537
0
{
538
0
  unsigned int r_type;
539
540
0
  r_type = ELF32_R_TYPE (dst->r_info);
541
0
  if (r_type >= (unsigned int) R_D30V_max)
542
0
    {
543
      /* xgettext:c-format */
544
0
      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
545
0
        abfd, r_type);
546
0
      bfd_set_error (bfd_error_bad_value);
547
0
      return false;
548
0
    }
549
0
  cache_ptr->howto = &elf_d30v_howto_table[r_type];
550
0
  return true;
551
0
}
552
553
#define ELF_ARCH    bfd_arch_d30v
554
#define ELF_MACHINE_CODE  EM_D30V
555
#define ELF_MACHINE_ALT1  EM_CYGNUS_D30V
556
#define ELF_MAXPAGESIZE   0x1000
557
558
#define TARGET_BIG_SYM    d30v_elf32_vec
559
#define TARGET_BIG_NAME   "elf32-d30v"
560
561
#define elf_info_to_howto d30v_info_to_howto_rela
562
#define elf_info_to_howto_rel d30v_info_to_howto_rel
563
#define elf_backend_object_p  0
564
565
#include "elf32-target.h"