2014-10-07 Martin Jambor <mjambor@suse.cz>
[official-gcc.git] / gcc / hsa-brig.c
blob1598adb089fd903fd5a26aa57ff1ad2c67e9825b
1 /* Producing binary form of HSA BRIG from our internal representation.
2 Copyright (C) 2013 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC 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.
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "hsa.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "stor-layout.h"
27 #include "tree-cfg.h"
28 #include "machmode.h"
29 #include "output.h"
30 #include "basic-block.h"
31 #include "vec.h"
32 #include "gimple-pretty-print.h"
33 #include "diagnostic-core.h"
35 #define BRIG_SECTION_DATA_NAME "hsa_data"
36 #define BRIG_SECTION_CODE_NAME "hsa_code"
37 #define BRIG_SECTION_OPERAND_NAME "hsa_operand"
39 #define BRIG_CHUNK_MAX_SIZE (64 * 1024)
41 /* FIXME: The code below uses endian.h routines to convert numbers to
42 little-endian. I suspect this only works on glibc platforms, so we might
43 need an alternative solutin later. */
45 /* Chunks of BRIG binary data. */
47 struct hsa_brig_data_chunk
49 /* Size of the data already stored into a chunk. */
50 unsigned size;
52 /* Pointer to the data. */
53 char *data;
56 /* Structure represeting a BRIC section, holding and writing its data. */
58 class hsa_brig_section
60 public:
61 /* Section name that will be output to the BRIG. */
62 const char *section_name;
63 /* Size in bytes of all data stored in the section. */
64 unsigned total_size, header_byte_count;
66 /* Buffers of binary data, each containing BRIG_CHUNK_MAX_SIZE bytes. */
67 vec <struct hsa_brig_data_chunk> chunks;
69 /* More convenient access to the last chunk from the vector above. */
70 struct hsa_brig_data_chunk *cur_chunk;
72 void allocate_new_chunk ();
73 void init (const char *name);
74 void release ();
75 void output ();
76 unsigned add (const void *data, unsigned len);
77 void round_size_up (int factor);
80 static struct hsa_brig_section brig_data, brig_code, brig_operand;
81 static uint32_t brig_insn_count;
82 static bool brig_initialized = false;
84 /* Add a new chunk, allocate data for it and initialize it. */
86 void
87 hsa_brig_section::allocate_new_chunk ()
89 struct hsa_brig_data_chunk new_chunk;
91 new_chunk.data = XCNEWVEC (char, BRIG_CHUNK_MAX_SIZE);
92 new_chunk.size = 0;
93 cur_chunk = chunks.safe_push (new_chunk);
96 /* Initialize the brig section. */
98 void
99 hsa_brig_section::init (const char *name)
101 struct BrigSectionHeader sample;
103 section_name = name;
104 total_size = sizeof(sample.byteCount) + sizeof(sample.headerByteCount)
105 + sizeof(sample.nameLength);
106 /* Add strlen + null termination to the section size*/
107 total_size = total_size + strlen(section_name) + 1;
108 chunks.create (1);
109 allocate_new_chunk ();
110 round_size_up (4);
111 header_byte_count = total_size;
114 /* Free all data in the section. */
116 void
117 hsa_brig_section::release ()
119 for (unsigned i = 0; i < chunks.length (); i++)
120 free (chunks[i].data);
121 chunks.release ();
122 cur_chunk = NULL;
125 /* Write the section to the output file to a section with the name given at
126 initialization. Switches the output section and does not restore it. */
128 void
129 hsa_brig_section::output ()
131 struct BrigSectionHeader section_header;
133 switch_to_section (get_section (section_name, SECTION_NOTYPE, NULL));
135 section_header.byteCount = htole32 (total_size);
136 section_header.nameLength = htole32 (strlen(section_name));
137 section_header.headerByteCount = htole32 (header_byte_count);
138 assemble_string ((const char*) &section_header, 12);
139 assemble_string (section_name, (section_header.nameLength + 1));
140 for (unsigned i = 0; i < chunks.length (); i++)
141 assemble_string (chunks[i].data, chunks[i].size);
144 /* Add to the stream LEN bytes of opaque binary DATA. Return the offset at
145 which it was stored. */
147 unsigned
148 hsa_brig_section::add (const void *data, unsigned len)
150 unsigned offset = total_size;
152 gcc_assert (len <= BRIG_CHUNK_MAX_SIZE);
153 if (cur_chunk->size > (BRIG_CHUNK_MAX_SIZE - len))
154 allocate_new_chunk ();
156 memcpy (cur_chunk->data + cur_chunk->size, data, len);
157 cur_chunk->size += len;
158 total_size += len;
160 return offset;
163 /* Add padding to section so that its size is divisble by FACTOR. */
165 void
166 hsa_brig_section::round_size_up (int factor)
168 unsigned padding, res = total_size % factor;
170 if (res == 0)
171 return;
173 padding = factor - res;
174 total_size += padding;
175 if (cur_chunk->size > (BRIG_CHUNK_MAX_SIZE - padding))
177 padding -= BRIG_CHUNK_MAX_SIZE - cur_chunk->size;
178 cur_chunk->size = BRIG_CHUNK_MAX_SIZE;
179 allocate_new_chunk ();
182 cur_chunk->size += padding;
185 /* BRIG string data hashing. */
187 struct brig_string_slot
189 const char *s;
190 char prefix;
191 int len;
192 uint32_t offset;
195 /* Hashtable helpers. */
197 struct brig_string_slot_hasher
199 typedef brig_string_slot value_type;
200 typedef brig_string_slot compare_type;
201 static inline hashval_t hash (const value_type *);
202 static inline bool equal (const value_type *, const compare_type *);
203 static inline void remove (value_type *);
206 /* Returns a hash code for DS. Adapted from libiberty's htab_hash_string
207 to support strings that may not end in '\0'. */
209 inline hashval_t
210 brig_string_slot_hasher::hash (const value_type *ds)
212 hashval_t r = ds->len;
213 int i;
215 for (i = 0; i < ds->len; i++)
216 r = r * 67 + (unsigned)ds->s[i] - 113;
217 r = r * 67 + (unsigned)ds->prefix - 113;
218 return r;
221 /* Returns nonzero if DS1 and DS2 are equal. */
223 inline bool
224 brig_string_slot_hasher::equal (const value_type *ds1, const compare_type *ds2)
226 if (ds1->len == ds2->len)
227 return ds1->prefix == ds2->prefix && memcmp (ds1->s, ds2->s, ds1->len) == 0;
229 return 0;
232 inline void
233 brig_string_slot_hasher::remove (value_type *ds)
235 free (const_cast<char*> (ds->s));
238 static hash_table<brig_string_slot_hasher> *brig_string_htab;
240 static void
241 sanitize_hsa_name (char *p)
243 for (; *p; p++)
244 if (*p == '.')
245 *p = '_';
248 /* Emit a null terminated string STR to the data section and return its
249 offset in it. If PREFIX is non-zero, output it just before STR too. */
251 static unsigned
252 brig_emit_string (const char *str, char prefix = 0)
254 unsigned slen = strlen (str);
255 unsigned offset, len = slen + (prefix ? 1 : 0);
256 uint32_t hdr_len = htole32 (len);
257 brig_string_slot s_slot;
258 brig_string_slot **slot;
259 char *str2;
261 /* XXX Sanitize the names without all the strdup. */
262 str2 = xstrdup (str);
263 sanitize_hsa_name (str2);
264 s_slot.s = str2;
265 s_slot.len = slen;
266 s_slot.prefix = prefix;
267 s_slot.offset = 0;
269 slot = brig_string_htab->find_slot (&s_slot, INSERT);
270 if (*slot == NULL)
272 brig_string_slot *new_slot = XCNEW (brig_string_slot);
274 /* In theory we should fill in BrigData but that would mean copying
275 the string to a buffer for no reason, so we just emaulate it. */
276 offset = brig_data.add (&hdr_len, sizeof (hdr_len));
277 if (prefix)
278 brig_data.add (&prefix, 1);
280 brig_data.add (str2, slen);
281 brig_data.round_size_up (4);
283 /* XXX could use the string we just copied into brig_string->cur_chunk */
284 new_slot->s = str2;
285 new_slot->len = slen;
286 new_slot->prefix = prefix;
287 new_slot->offset = offset;
288 *slot = new_slot;
290 else
292 offset = (*slot)->offset;
293 free (str2);
296 return offset;
299 /* Linked list of queued operands. */
301 static struct operand_queue
303 /* First from the chain of queued operands. */
304 hsa_op_base *first_op, *last_op;
306 /* The offset at which the next operand will be enqueued. */
307 unsigned projected_size;
309 } op_queue;
311 /* Unless already initialized, initialzie infrastructure to produce BRIG. */
313 static void
314 brig_init (void)
316 struct BrigDirectiveVersion verdir;
317 brig_insn_count = 0;
319 if (brig_initialized)
320 return;
322 brig_string_htab = new hash_table<brig_string_slot_hasher> (37);
323 brig_data.init (BRIG_SECTION_DATA_NAME);
324 brig_code.init (BRIG_SECTION_CODE_NAME);
325 brig_operand.init (BRIG_SECTION_OPERAND_NAME);
327 verdir.base.byteCount = htole16 (sizeof (verdir));
328 verdir.base.kind = htole16 (BRIG_KIND_DIRECTIVE_VERSION);
329 verdir.hsailMajor = htole32 (BRIG_VERSION_HSAIL_MAJOR) ;
330 verdir.hsailMinor = htole32 (BRIG_VERSION_HSAIL_MINOR);
331 verdir.brigMajor = htole32 (BRIG_VERSION_BRIG_MAJOR);
332 verdir.brigMinor = htole32 (BRIG_VERSION_BRIG_MINOR);
333 verdir.profile = hsa_full_profile_p () ? BRIG_PROFILE_FULL: BRIG_PROFILE_BASE;
334 if (hsa_machine_large_p ())
335 verdir.machineModel = BRIG_MACHINE_LARGE;
336 else
337 verdir.machineModel = BRIG_MACHINE_SMALL;
338 verdir.reserved = 0;
339 brig_code.add (&verdir, sizeof (verdir));
340 brig_initialized = true;
343 /* Free all BRIG data. */
345 static void
346 brig_release_data (void)
348 delete brig_string_htab;
349 brig_data.release ();
350 brig_code.release ();
351 brig_operand.release ();
353 brig_initialized = 0;
356 /* Find the alignment base on the type. */
358 static BrigAlignment8_t
359 get_alignment (BrigType16_t type)
361 BrigType16_t bit_type ;
362 bit_type = bittype_for_type (type) ;
364 if (bit_type == BRIG_TYPE_B1)
365 return BRIG_ALIGNMENT_1;
366 if (bit_type == BRIG_TYPE_B8)
367 return BRIG_ALIGNMENT_1;
368 if (bit_type == BRIG_TYPE_B16)
369 return BRIG_ALIGNMENT_2;
370 if (bit_type == BRIG_TYPE_B32)
371 return BRIG_ALIGNMENT_4;
372 if (bit_type == BRIG_TYPE_B64)
373 return BRIG_ALIGNMENT_8;
374 if (bit_type == BRIG_TYPE_B128)
375 return BRIG_ALIGNMENT_16;
376 gcc_unreachable ();
379 /* Emit directive describing a symbol if it has not been emitted already.
380 Return the offset of the directive. */
382 static unsigned
383 emit_directive_variable (struct hsa_symbol *symbol)
385 struct BrigDirectiveVariable dirvar;
386 unsigned name_offset;
387 static unsigned res_name_offset;
388 char prefix;
390 if (symbol->offset)
391 return symbol->offset;
393 dirvar.base.byteCount = htole16 (sizeof (dirvar));
394 dirvar.base.kind = htole16 (BRIG_KIND_DIRECTIVE_VARIABLE);
395 dirvar.allocation = BRIG_ALLOCATION_AUTOMATIC;
397 if (symbol->decl && is_global_var (symbol->decl))
399 prefix = '&';
400 dirvar.allocation = BRIG_ALLOCATION_PROGRAM ;
401 if (TREE_CODE (symbol->decl) == VAR_DECL)
402 warning (0, "referring to global symbol %q+D by name from HSA code won't work", symbol->decl);
404 else
405 prefix = '%';
407 if (symbol->decl && TREE_CODE (symbol->decl) == RESULT_DECL)
409 if (res_name_offset == 0)
410 res_name_offset = brig_emit_string (symbol->name, '%');
411 name_offset = res_name_offset;
412 dirvar.allocation = BRIG_ALLOCATION_NONE;
414 else if (symbol->name)
415 name_offset = brig_emit_string (symbol->name, prefix);
416 else
418 char buf[64];
419 sprintf (buf, "__%s_%i", hsa_seg_name (symbol->segment),
420 symbol->name_number);
421 name_offset = brig_emit_string (buf, prefix);
424 dirvar.name = htole32 (name_offset);
425 dirvar.init = 0;
426 dirvar.type = htole16 (symbol->type);
427 dirvar.segment = symbol->segment;
428 dirvar.align = get_alignment (dirvar.type);
429 dirvar.linkage = BRIG_LINKAGE_FUNCTION ;
430 dirvar.dim.lo = htole32 (symbol->dimLo);
431 dirvar.dim.hi = htole32 (symbol->dimHi);
432 dirvar.modifier = BRIG_SYMBOL_DEFINITION;
433 dirvar.reserved = 0;
435 symbol->offset = brig_code.add (&dirvar, sizeof (dirvar));
436 return symbol->offset;
439 /* Emit directives describing the function, for example its input and output
440 arguments, local variables etc. */
442 static BrigDirectiveExecutable *
443 emit_function_directives (void)
445 struct BrigDirectiveExecutable fndir;
446 unsigned name_offset, inarg_off, scoped_off, next_toplev_off;
447 int count = 0;
448 BrigDirectiveExecutable *ptr_to_fndir;
449 hsa_symbol *sym;
451 name_offset = brig_emit_string (hsa_cfun.name, '&');
452 inarg_off = brig_code.total_size + sizeof(fndir)
453 + (hsa_cfun.output_arg ? sizeof (struct BrigDirectiveVariable) : 0);
454 scoped_off = inarg_off
455 + hsa_cfun.input_args_count * sizeof (struct BrigDirectiveVariable);
456 for (hash_table <hsa_noop_symbol_hasher>::iterator iter
457 = hsa_cfun.local_symbols->begin ();
458 iter != hsa_cfun.local_symbols->end ();
459 ++iter)
460 if (TREE_CODE ((*iter)->decl) == VAR_DECL)
461 count++;
462 count += hsa_cfun.spill_symbols.length();
464 next_toplev_off = scoped_off + count * sizeof (struct BrigDirectiveVariable);
466 fndir.base.byteCount = htole16 (sizeof (fndir));
467 fndir.base.kind = htole16 (BRIG_KIND_DIRECTIVE_KERNEL);
468 fndir.name = htole32 (name_offset);
469 fndir.inArgCount = htole16 (hsa_cfun.input_args_count);
470 fndir.outArgCount = htole16 (hsa_cfun.output_arg ? 1 : 0);
471 fndir.firstInArg = htole32 (inarg_off);
472 fndir.firstCodeBlockEntry = htole32 (scoped_off);
473 fndir.nextModuleEntry = htole32 (next_toplev_off);
474 fndir.linkage = BRIG_LINKAGE_PROGRAM;
475 fndir.codeBlockEntryCount = htole32 (0);
476 fndir.modifier = BRIG_EXECUTABLE_DEFINITION;
477 memset (&fndir.reserved, 0, sizeof (fndir.reserved));
479 brig_code.add (&fndir, sizeof (fndir));
480 /* XXX terrible hack: we need to set instCount after we emit all
481 insns, but we need to emit directive in order, and we emit directives
482 during insn emitting. So we need to emit the FUNCTION directive
483 early, then the insns, and then we need to set instCount, so remember
484 a pointer to it, in some horrible way. cur_chunk.data+size points
485 directly to after fndir here. */
486 ptr_to_fndir
487 = (BrigDirectiveExecutable *)(brig_code.cur_chunk->data
488 + brig_code.cur_chunk->size
489 - sizeof (fndir));
491 if (hsa_cfun.output_arg)
492 emit_directive_variable(hsa_cfun.output_arg);
493 for (int i = 0; i < hsa_cfun.input_args_count; i++)
494 emit_directive_variable(&hsa_cfun.input_args[i]);
495 for (hash_table <hsa_noop_symbol_hasher>::iterator iter
496 = hsa_cfun.local_symbols->begin ();
497 iter != hsa_cfun.local_symbols->end ();
498 ++iter)
499 emit_directive_variable(*iter);
500 for (int i = 0; hsa_cfun.spill_symbols.iterate (i, &sym); i++)
502 emit_directive_variable (sym);
503 brig_insn_count++;
505 return ptr_to_fndir;
508 /* Emit a label directive for the given HBB. We assume it is about to start on
509 the current offset in the code section. */
511 static void
512 emit_bb_label_directive (hsa_bb *hbb)
514 struct BrigDirectiveLabel lbldir;
515 char buf[32];
517 lbldir.base.byteCount = htole16 (sizeof (lbldir));
518 lbldir.base.kind = htole16 (BRIG_KIND_DIRECTIVE_LABEL);
519 sprintf (buf, "BB_%u_%i", DECL_UID (current_function_decl), hbb->index);
520 lbldir.name = htole32 (brig_emit_string (buf, '@'));
522 hbb->label_ref.directive_offset = brig_code.add (&lbldir, sizeof (lbldir));
523 brig_insn_count++;
526 BrigType16_t
527 bittype_for_type (BrigType16_t t)
529 switch (t)
531 case BRIG_TYPE_B1:
532 return BRIG_TYPE_B1;
534 case BRIG_TYPE_U8:
535 case BRIG_TYPE_S8:
536 case BRIG_TYPE_B8:
537 return BRIG_TYPE_B8;
539 case BRIG_TYPE_U16:
540 case BRIG_TYPE_S16:
541 case BRIG_TYPE_B16:
542 case BRIG_TYPE_F16:
543 return BRIG_TYPE_B16;
545 case BRIG_TYPE_U32:
546 case BRIG_TYPE_S32:
547 case BRIG_TYPE_B32:
548 case BRIG_TYPE_F32:
549 case BRIG_TYPE_U8X4:
550 case BRIG_TYPE_U16X2:
551 case BRIG_TYPE_S8X4:
552 case BRIG_TYPE_S16X2:
553 case BRIG_TYPE_F16X2:
554 return BRIG_TYPE_B32;
556 case BRIG_TYPE_U64:
557 case BRIG_TYPE_S64:
558 case BRIG_TYPE_F64:
559 case BRIG_TYPE_B64:
560 case BRIG_TYPE_U8X8:
561 case BRIG_TYPE_U16X4:
562 case BRIG_TYPE_U32X2:
563 case BRIG_TYPE_S8X8:
564 case BRIG_TYPE_S16X4:
565 case BRIG_TYPE_S32X2:
566 case BRIG_TYPE_F16X4:
567 case BRIG_TYPE_F32X2:
569 return BRIG_TYPE_B64;
571 case BRIG_TYPE_B128:
572 case BRIG_TYPE_U8X16:
573 case BRIG_TYPE_U16X8:
574 case BRIG_TYPE_U32X4:
575 case BRIG_TYPE_U64X2:
576 case BRIG_TYPE_S8X16:
577 case BRIG_TYPE_S16X8:
578 case BRIG_TYPE_S32X4:
579 case BRIG_TYPE_S64X2:
580 case BRIG_TYPE_F16X8:
581 case BRIG_TYPE_F32X4:
582 case BRIG_TYPE_F64X2:
583 return BRIG_TYPE_B128;
585 default:
586 gcc_assert (seen_error ());
587 return t;
591 /* Map a normal HSAIL type to the type of the equivalent BRIG operand
592 holding such, for constants and registers. */
594 static BrigType16_t
595 regtype_for_type (BrigType16_t t)
597 switch (t)
599 case BRIG_TYPE_B1:
600 return BRIG_TYPE_B1;
602 case BRIG_TYPE_U8:
603 case BRIG_TYPE_U16:
604 case BRIG_TYPE_U32:
605 case BRIG_TYPE_S8:
606 case BRIG_TYPE_S16:
607 case BRIG_TYPE_S32:
608 case BRIG_TYPE_B8:
609 case BRIG_TYPE_B16:
610 case BRIG_TYPE_B32:
611 case BRIG_TYPE_F16:
612 case BRIG_TYPE_F32:
613 case BRIG_TYPE_U8X4:
614 case BRIG_TYPE_U16X2:
615 case BRIG_TYPE_S8X4:
616 case BRIG_TYPE_S16X2:
617 case BRIG_TYPE_F16X2:
618 return BRIG_TYPE_B32;
620 case BRIG_TYPE_U64:
621 case BRIG_TYPE_S64:
622 case BRIG_TYPE_F64:
623 case BRIG_TYPE_B64:
624 case BRIG_TYPE_U8X8:
625 case BRIG_TYPE_U16X4:
626 case BRIG_TYPE_U32X2:
627 case BRIG_TYPE_S8X8:
628 case BRIG_TYPE_S16X4:
629 case BRIG_TYPE_S32X2:
630 case BRIG_TYPE_F16X4:
631 case BRIG_TYPE_F32X2:
633 return BRIG_TYPE_B64;
635 case BRIG_TYPE_B128:
636 case BRIG_TYPE_U8X16:
637 case BRIG_TYPE_U16X8:
638 case BRIG_TYPE_U32X4:
639 case BRIG_TYPE_U64X2:
640 case BRIG_TYPE_S8X16:
641 case BRIG_TYPE_S16X8:
642 case BRIG_TYPE_S32X4:
643 case BRIG_TYPE_S64X2:
644 case BRIG_TYPE_F16X8:
645 case BRIG_TYPE_F32X4:
646 case BRIG_TYPE_F64X2:
647 return BRIG_TYPE_B128;
649 default:
650 gcc_unreachable ();
654 /* Enqueue operation OP. Return the offset at which it will be stored. */
656 unsigned int
657 enqueue_op (hsa_op_base *op)
659 unsigned ret;
661 if (op->offset)
662 return op->offset;
664 ret = op_queue.projected_size;
665 op->offset = op_queue.projected_size;
667 if (!op_queue.first_op)
668 op_queue.first_op = op;
669 else
670 op_queue.last_op->next = op;
671 op_queue.last_op = op;
673 if (is_a <hsa_op_immed *> (op))
674 op_queue.projected_size += sizeof (struct BrigOperandData);
675 else if (is_a <hsa_op_reg *> (op))
676 op_queue.projected_size += sizeof (struct BrigOperandReg);
677 else if (is_a <hsa_op_address *> (op))
679 op_queue.projected_size += sizeof (struct BrigOperandAddress);
681 else if (is_a <hsa_op_label *> (op))
682 op_queue.projected_size += sizeof (struct BrigOperandCodeRef);
683 else
684 gcc_unreachable ();
685 return ret;
688 /* Emit an immediate BRIG operand IMM. */
690 static void
691 emit_immediate_operand (hsa_op_immed *imm)
693 struct BrigOperandData out;
694 uint32_t byteCount;
696 union
698 uint8_t b8;
699 uint16_t b16;
700 uint32_t b32;
701 uint64_t b64;
702 } bytes;
703 unsigned len;
705 switch (imm->type)
707 case BRIG_TYPE_U8:
708 case BRIG_TYPE_S8:
709 len = 1;
710 bytes.b8 = (uint8_t) TREE_INT_CST_LOW (imm->value);
711 break;
712 case BRIG_TYPE_U16:
713 case BRIG_TYPE_S16:
714 bytes.b16 = (uint16_t) TREE_INT_CST_LOW (imm->value);
715 len = 2;
716 break;
718 case BRIG_TYPE_F16:
719 sorry ("Support for HSA does not implement immediate 16 bit FPU "
720 "operands");
721 len = 2;
722 break;
724 case BRIG_TYPE_U32:
725 case BRIG_TYPE_S32:
726 bytes.b32 = (uint32_t) TREE_INT_CST_LOW (imm->value);
727 len = 4;
728 break;
730 case BRIG_TYPE_U64:
731 case BRIG_TYPE_S64:
732 bytes.b64 = (uint64_t) int_cst_value (imm->value);
733 len = 8;
734 break;
736 case BRIG_TYPE_F32:
737 case BRIG_TYPE_F64:
739 tree expr = imm->value;
740 tree type = TREE_TYPE (expr);
742 len = GET_MODE_SIZE (TYPE_MODE (type));
744 /* There are always 32 bits in each long, no matter the size of
745 the hosts long. */
746 long tmp[6];
748 gcc_assert (len == 4 || len == 8);
750 real_to_target (tmp, TREE_REAL_CST_PTR (expr), TYPE_MODE (type));
752 if (len == 4)
753 bytes.b32 = (uint32_t) tmp[0];
754 else
756 bytes.b64 = (uint64_t)(uint32_t) tmp[1];
757 bytes.b64 <<= 32;
758 bytes.b64 |= (uint32_t) tmp[0];
761 break;
764 case BRIG_TYPE_U8X4:
765 case BRIG_TYPE_S8X4:
766 case BRIG_TYPE_U16X2:
767 case BRIG_TYPE_S16X2:
768 case BRIG_TYPE_F16X2:
769 len = 4;
770 sorry ("Support for HSA does not implement immediate 32bit "
771 "vector operands. ");
772 break;
774 case BRIG_TYPE_U8X8:
775 case BRIG_TYPE_S8X8:
776 case BRIG_TYPE_U16X4:
777 case BRIG_TYPE_S16X4:
778 case BRIG_TYPE_F16X4:
779 case BRIG_TYPE_U32X2:
780 case BRIG_TYPE_S32X2:
781 case BRIG_TYPE_F32X2:
782 len = 8;
783 sorry ("Support for HSA does not implement immediate 32bit "
784 "vector operands. ");
785 break;
787 default:
788 gcc_unreachable ();
791 out.base.byteCount = htole16 (sizeof (out));
792 out.base.kind = htole16 (BRIG_KIND_OPERAND_DATA);
793 byteCount = len ;
795 out.data = brig_data.add (&byteCount, sizeof (byteCount));
796 brig_data.add (&bytes, len);
798 brig_operand.add (&out, sizeof(out));
799 brig_data.round_size_up (4);
802 /* Emit a register BRIG operand REG. */
804 static void
805 emit_register_operand (hsa_op_reg *reg)
807 struct BrigOperandReg out;
809 out.base.byteCount = htole16 (sizeof (out));
810 out.base.kind = htole16 (BRIG_KIND_OPERAND_REG);
811 out.regNum = htole32 (reg->hard_num);
813 if (BRIG_TYPE_B32 == regtype_for_type (reg->type))
814 out.regKind = BRIG_REGISTER_SINGLE;
815 else if (BRIG_TYPE_B64 == regtype_for_type (reg->type))
816 out.regKind = BRIG_REGISTER_DOUBLE;
817 else if (BRIG_TYPE_B128 == regtype_for_type (reg->type))
818 out.regKind = BRIG_REGISTER_QUAD;
819 else if (BRIG_TYPE_B1 == regtype_for_type (reg->type))
820 out.regKind = BRIG_REGISTER_CONTROL;
821 else
822 gcc_unreachable ();
824 brig_operand.add (&out, sizeof (out));
827 /* Emit an address BRIG operand ADDR. */
829 static void
830 emit_address_operand (hsa_op_address *addr)
832 struct BrigOperandAddress out;
834 out.base.byteCount = htole16 (sizeof (out));
835 out.base.kind = htole16 (BRIG_KIND_OPERAND_ADDRESS);
836 out.symbol = addr->symbol
837 ? htole32 (emit_directive_variable (addr->symbol)) : 0;
838 out.reg = addr->reg ? htole32 (enqueue_op (addr->reg)) : 0;
840 /* FIXME: This is very clumsy. */
841 if (sizeof (addr->imm_offset) == 8)
843 out.offset.lo = htole32 ((uint32_t)addr->imm_offset);
844 out.offset.hi = htole32 (((long long) addr->imm_offset) >> 32);
846 else
848 out.offset.lo = htole32 (addr->imm_offset);
849 out.offset.hi = 0;
852 brig_operand.add (&out, sizeof (out));
855 /* Emit a label BRIG operand LABEL. */
857 static void
858 emit_label_operand (hsa_op_label *lbl)
860 struct BrigOperandCodeRef out;
862 gcc_assert (lbl->directive_offset);
863 out.base.byteCount = htole16 (sizeof (out));
864 out.base.kind = htole16 (BRIG_KIND_OPERAND_CODE_REF);
865 out.ref = htole32 (lbl->directive_offset);
866 brig_operand.add (&out, sizeof (out));
869 /* Emit all operands queued for writing. */
871 static void
872 emit_queued_operands (void)
874 for (hsa_op_base *op = op_queue.first_op; op; op = op->next)
876 gcc_assert (op->offset == brig_operand.total_size);
877 if (hsa_op_immed *imm = dyn_cast <hsa_op_immed *> (op))
878 emit_immediate_operand (imm);
879 else if (hsa_op_reg *reg = dyn_cast <hsa_op_reg *> (op))
880 emit_register_operand (reg);
881 else if (hsa_op_address *addr = dyn_cast <hsa_op_address *> (op))
882 emit_address_operand (addr);
883 else if (hsa_op_label *lbl = dyn_cast <hsa_op_label *> (op))
884 emit_label_operand (lbl);
885 else
886 gcc_unreachable ();
890 /* Emit an HSA memory instruction and all necessary directives, schedule
891 necessary operands for writing . */
893 static void
894 emit_memory_insn (hsa_insn_mem *mem)
896 struct BrigInstMem repr;
897 BrigOperandOffset32_t operand_offsets[2];
898 uint32_t byteCount;
900 hsa_op_address *addr = as_a <hsa_op_address *> (mem->operands[1]);
902 /* This is necessary because of the errorneous typedef of
903 BrigMemoryModifier8_t which introduces padding which may then contain
904 random stuff (which we do not want so that we can test things don't
905 change). */
906 memset (&repr, 0, sizeof (repr));
907 repr.base.base.byteCount = htole16 (sizeof (repr));
908 repr.base.base.kind = htole16 (BRIG_KIND_INST_MEM);
909 repr.base.opcode = htole16 (mem->opcode);
910 repr.base.type = htole16 (mem->type);
912 operand_offsets[0] = htole32 (enqueue_op (mem->operands[0]));
913 operand_offsets[1] = htole32 (enqueue_op (mem->operands[1]));
914 /* We have two operands so use 4 * 2 for the byteCount */
915 byteCount = htole32 (4 * 2);
917 repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
918 brig_data.add (&operand_offsets, sizeof (operand_offsets));
919 brig_data.round_size_up (4);
921 if (addr->symbol)
922 repr.segment = addr->symbol->segment;
923 else
924 repr.segment = BRIG_SEGMENT_FLAT;
925 repr.modifier = 0 ;
926 repr.equivClass = mem->equiv_class;
927 repr.align = BRIG_ALIGNMENT_1;
928 if (mem->opcode == BRIG_OPCODE_LD)
929 repr.width = BRIG_WIDTH_1;
930 else
931 repr.width = BRIG_WIDTH_NONE;
932 memset (&repr.reserved, 0, sizeof (repr.reserved));
933 brig_code.add (&repr, sizeof (repr));
934 brig_insn_count++;
937 /* Emit an HSA memory instruction and all necessary directives, schedule
938 necessary operands for writing . */
940 static void
941 emit_atomic_insn (hsa_insn_atomic *mem)
943 struct BrigInstAtomic repr;
944 BrigOperandOffset32_t operand_offsets[4];
945 uint32_t byteCount;
947 hsa_op_address *addr = as_a <hsa_op_address *> (mem->operands[1]);
949 /* This is necessary because of the errorneous typedef of
950 BrigMemoryModifier8_t which introduces padding which may then contain
951 random stuff (which we do not want so that we can test things don't
952 change). */
953 memset (&repr, 0, sizeof (repr));
954 repr.base.base.byteCount = htole16 (sizeof (repr));
955 repr.base.base.kind = htole16 (BRIG_KIND_INST_ATOMIC);
956 repr.base.opcode = htole16 (mem->opcode);
957 repr.base.type = htole16 (mem->type);
959 operand_offsets[0] = htole32 (enqueue_op (mem->operands[0]));
960 operand_offsets[1] = htole32 (enqueue_op (mem->operands[1]));
961 operand_offsets[2] = htole32 (enqueue_op (mem->operands[2]));
962 operand_offsets[3] = htole32 (enqueue_op (mem->operands[3]));
964 /* We have 4 operands so use 4 * 4 for the byteCount */
965 byteCount = htole32 (4 * 4);
967 repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
968 brig_data.add (&operand_offsets, sizeof (operand_offsets));
969 brig_data.round_size_up (4);
971 if (addr->symbol)
972 repr.segment = addr->symbol->segment;
973 else
974 repr.segment = BRIG_SEGMENT_FLAT;
975 repr.memoryOrder = mem->memoryorder;
976 repr.memoryScope = mem->memoryscope;
977 repr.atomicOperation = mem->atomicop;
979 brig_code.add (&repr, sizeof (repr));
980 brig_insn_count++;
983 /* Emit an HSA LDA instruction and all necessary directives, schedule
984 necessary operands for writing . */
986 static void
987 emit_addr_insn (hsa_insn_addr *insn)
989 struct BrigInstAddr repr;
990 BrigOperandOffset32_t operand_offsets[2];
991 uint32_t byteCount;
993 hsa_op_address *addr = as_a <hsa_op_address *> (insn->operands[1]);
995 repr.base.base.byteCount = htole16 (sizeof (repr));
996 repr.base.base.kind = htole16 (BRIG_KIND_INST_ADDR);
997 repr.base.opcode = htole16 (insn->opcode);
998 repr.base.type = htole16 (insn->type);
1000 operand_offsets[0] = htole32 (enqueue_op (insn->operands[0]));
1001 operand_offsets[1] = htole32 (enqueue_op (insn->operands[1]));
1003 /* We have two operands so use 4 * 2 for the byteCount */
1004 byteCount = htole32 (4 * 2);
1006 repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
1007 brig_data.add (&operand_offsets, sizeof (operand_offsets));
1008 brig_data.round_size_up (4);
1010 if (addr->symbol)
1011 repr.segment = addr->symbol->segment;
1012 else
1013 repr.segment = BRIG_SEGMENT_FLAT;
1014 memset (&repr.reserved, 0, sizeof (repr.reserved));
1016 brig_code.add (&repr, sizeof (repr));
1017 brig_insn_count++;
1020 /* Emit an HSA segment conversion instruction and all necessary directives,
1021 schedule necessary operands for writing . */
1023 static void
1024 emit_segment_insn (hsa_insn_seg *seg)
1026 struct BrigInstSeg repr;
1027 BrigOperandOffset32_t operand_offsets[2];
1028 uint32_t byteCount;
1030 repr.base.base.byteCount = htole16 (sizeof (repr));
1031 repr.base.base.kind = htole16 (BRIG_KIND_INST_SEG);
1032 repr.base.opcode = htole16 (seg->opcode);
1033 repr.base.type = htole16 (seg->type);
1035 operand_offsets[0] = htole32 (enqueue_op (seg->operands[0]));
1036 operand_offsets[1] = htole32 (enqueue_op (seg->operands[1]));
1038 /* We have two operands so use 4 * 2 for the byteCount */
1039 byteCount = htole32 (4 * 2);
1041 repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
1042 brig_data.add (&operand_offsets, sizeof (operand_offsets));
1043 brig_data.round_size_up (4);
1045 repr.segment = seg->segment;
1046 memset (&repr.reserved, 0, sizeof (repr.reserved));
1048 brig_code.add (&repr, sizeof (repr));
1050 brig_insn_count++;
1053 /* Emit an HSA comparison instruction and all necessary directives,
1054 schedule necessary operands for writing . */
1056 static void
1057 emit_cmp_insn (hsa_insn_cmp *cmp)
1059 struct BrigInstCmp repr;
1060 BrigOperandOffset32_t operand_offsets[3];
1061 uint32_t byteCount;
1063 repr.base.base.byteCount = htole16 (sizeof (repr));
1064 repr.base.base.kind = htole16 (BRIG_KIND_INST_CMP);
1065 repr.base.opcode = htole16 (cmp->opcode);
1066 repr.base.type = htole16 (cmp->type);
1068 operand_offsets[0] = htole32 (enqueue_op (cmp->operands[0]));
1069 operand_offsets[1] = htole32 (enqueue_op (cmp->operands[1]));
1070 operand_offsets[2] = htole32 (enqueue_op (cmp->operands[2]));
1071 /* We have three operands so use 4 * 3 for the byteCount */
1072 byteCount = htole32 (4 * 3);
1074 repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
1075 brig_data.add (&operand_offsets, sizeof (operand_offsets));
1076 brig_data.round_size_up (4);
1078 if (is_a <hsa_op_reg *> (cmp->operands[1]))
1079 repr.sourceType = htole16 (as_a <hsa_op_reg *> (cmp->operands[1])->type);
1080 else
1081 repr.sourceType = htole16 (as_a <hsa_op_immed *> (cmp->operands[1])->type);
1082 repr.modifier = 0;
1083 repr.compare = cmp->compare;
1084 repr.pack = 0;
1085 repr.reserved = 0;
1087 brig_code.add (&repr, sizeof (repr));
1088 brig_insn_count++;
1091 /* Emit an HSA branching instruction and all necessary directives, schedule
1092 necessary operands for writing . */
1094 static void
1095 emit_branch_insn (hsa_insn_br *br)
1097 struct BrigInstBr repr;
1098 BrigOperandOffset32_t operand_offsets[2];
1099 uint32_t byteCount;
1101 basic_block target = NULL;
1102 edge_iterator ei;
1103 edge e;
1105 /* At the moment we only handle direct conditional jumps. */
1106 gcc_assert (br->opcode == BRIG_OPCODE_CBR
1107 && !br->operands[2]);
1108 repr.base.base.byteCount = htole16 (sizeof (repr));
1109 repr.base.base.kind = htole16 (BRIG_KIND_INST_BR);
1110 repr.base.opcode = htole16 (br->opcode);
1111 repr.width = BRIG_WIDTH_1;
1112 /* For Conditional jumps the type is always B1 */
1113 repr.base.type = htole16 (BRIG_TYPE_B1);
1115 operand_offsets[0] = htole32 (enqueue_op (br->operands[0]));
1117 FOR_EACH_EDGE (e, ei, br->bb->succs)
1118 if (e->flags & EDGE_TRUE_VALUE)
1120 target = e->dest;
1121 break;
1123 gcc_assert (target);
1124 operand_offsets[1] = htole32 (enqueue_op
1125 (&hsa_bb_for_bb (target)->label_ref));
1127 /* We have 2 operands so use 4 * 2 for the byteCount */
1128 byteCount = htole32 (4 * 2);
1129 repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
1130 brig_data.add (&operand_offsets, sizeof (operand_offsets));
1131 brig_data.round_size_up (4);
1132 repr.width = BRIG_WIDTH_1;
1133 memset (&repr.reserved, 0, sizeof (repr.reserved));
1135 brig_code.add (&repr, sizeof (repr));
1136 brig_insn_count++;
1139 static bool
1140 float_type_p (BrigType16_t t)
1142 switch (t & BRIG_TYPE_BASE_MASK)
1144 case BRIG_TYPE_F16:
1145 case BRIG_TYPE_F32:
1146 case BRIG_TYPE_F64:
1147 return true;
1148 default:
1149 return false;
1153 /* Emit a HSA convert instruction and all necessary directives, schedule
1154 necessary operands for writing. */
1156 static void
1157 emit_cvt_insn (hsa_insn_basic *insn)
1159 struct BrigInstCvt repr;
1160 BrigType16_t srctype;
1161 BrigOperandOffset32_t operand_offsets[1];
1162 uint32_t byteCount, operand_count=0;
1164 repr.base.base.byteCount = htole16 (sizeof (repr));
1165 repr.base.base.kind = htole16 (BRIG_KIND_INST_CVT);
1166 repr.base.opcode = htole16 (insn->opcode);
1167 repr.base.type = htole16 (insn->type);
1169 for (int i = 0; i < HSA_OPERANDS_PER_INSN; i++)
1170 if (insn->operands[i])
1172 operand_offsets[i] = htole32 (enqueue_op (insn->operands[i]));
1173 operand_count = operand_count + 1;
1175 else
1176 operand_offsets[i] = 0;
1178 byteCount = htole32 (4 * operand_count) ;
1179 repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
1180 brig_data.add (&operand_offsets,
1181 operand_count * sizeof (BrigOperandOffset32_t));
1183 if (is_a <hsa_op_reg *> (insn->operands[1]))
1184 srctype = as_a <hsa_op_reg *> (insn->operands[1])->type;
1185 else
1186 srctype = as_a <hsa_op_immed *> (insn->operands[1])->type;
1187 repr.sourceType = htole16 (srctype);
1189 /* float to smaller float requires a rounding setting (we default
1190 to 'near'. */
1191 if (float_type_p (insn->type) && float_type_p (srctype)
1192 && (insn->type & BRIG_TYPE_BASE_MASK) < (srctype & BRIG_TYPE_BASE_MASK))
1193 repr.modifier = BRIG_ROUND_FLOAT_NEAR_EVEN;
1194 else
1195 repr.modifier = 0;
1197 brig_code.add (&repr, sizeof (repr));
1198 brig_insn_count++;
1201 /* Emit a basic HSA instruction and all necessary directives, schedule
1202 necessary operands for writing . */
1204 static void
1205 emit_basic_insn (hsa_insn_basic *insn)
1207 /* We assume that BrigInstMod has a BrigInstBasic prefix. */
1208 struct BrigInstMod repr;
1209 BrigType16_t type;
1210 BrigOperandOffset32_t operand_offsets[HSA_OPERANDS_PER_INSN];
1211 uint32_t byteCount, operand_count = 0;
1213 if (insn->opcode == BRIG_OPCODE_CVT)
1215 emit_cvt_insn (insn);
1216 return;
1219 repr.base.base.byteCount = htole16 (sizeof (BrigInstBasic));
1220 repr.base.base.kind = htole16 (BRIG_KIND_INST_BASIC);
1221 repr.base.opcode = htole16 (insn->opcode);
1222 switch (insn->opcode)
1224 /* XXX The spec says mov can take all types. But the LLVM based
1225 simulator cries about "Mov_s32" not being defined. */
1226 case BRIG_OPCODE_MOV:
1227 /* And the bit-logical operations need bit types and whine about
1228 arithmetic types :-/ */
1229 case BRIG_OPCODE_AND:
1230 case BRIG_OPCODE_OR:
1231 case BRIG_OPCODE_XOR:
1232 case BRIG_OPCODE_NOT:
1233 type = regtype_for_type (insn->type);
1234 break;
1235 default:
1236 type = insn->type;
1237 break;
1239 repr.base.type = htole16 (type);
1241 for (int i = 0; i < HSA_OPERANDS_PER_INSN; i++)
1242 if (insn->operands[i])
1244 operand_offsets[i] = htole32 (enqueue_op (insn->operands[i]));
1245 operand_count = operand_count + 1;
1247 else
1248 operand_offsets[i] = 0;
1250 byteCount = htole32 (4 * operand_count) ;
1251 repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
1252 brig_data.add (&operand_offsets,
1253 operand_count * sizeof (BrigOperandOffset32_t));
1254 brig_data.round_size_up (4);
1256 if ((type & BRIG_TYPE_PACK_MASK) != BRIG_TYPE_PACK_NONE)
1258 if (float_type_p (type))
1259 repr.modifier = BRIG_ROUND_FLOAT_NEAR_EVEN;
1260 else
1261 repr.modifier = 0;
1262 /* We assume that destination and sources agree in packing
1263 layout. */
1264 if (insn->operands[2])
1265 repr.pack = BRIG_PACK_PP;
1266 else
1267 repr.pack = BRIG_PACK_P;
1268 repr.reserved = 0;
1269 repr.base.base.byteCount = htole16 (sizeof (BrigInstMod));
1270 repr.base.base.kind = htole16 (BRIG_KIND_INST_MOD);
1271 brig_code.add (&repr, sizeof (struct BrigInstMod));
1273 else
1274 brig_code.add (&repr, sizeof (struct BrigInstBasic));
1275 brig_insn_count++;
1278 /* Emit an HSA instruction and all necessary directives, schedule necessary
1279 operands for writing . */
1281 static void
1282 emit_insn (hsa_insn_basic *insn)
1284 gcc_assert (!is_a <hsa_insn_phi *> (insn));
1285 if (hsa_insn_atomic *atom = dyn_cast <hsa_insn_atomic *> (insn))
1287 emit_atomic_insn (atom);
1288 return;
1290 if (hsa_insn_mem *mem = dyn_cast <hsa_insn_mem *> (insn))
1292 emit_memory_insn (mem);
1293 return;
1295 if (hsa_insn_addr *addr = dyn_cast <hsa_insn_addr *> (insn))
1297 emit_addr_insn (addr);
1298 return;
1300 if (hsa_insn_seg *seg = dyn_cast <hsa_insn_seg *> (insn))
1302 emit_segment_insn (seg);
1303 return;
1305 if (hsa_insn_cmp *cmp = dyn_cast <hsa_insn_cmp *> (insn))
1307 emit_cmp_insn (cmp);
1308 return;
1310 if (hsa_insn_br *br = dyn_cast <hsa_insn_br *> (insn))
1312 emit_branch_insn (br);
1313 return;
1315 emit_basic_insn (insn);
1318 /* We have just finished emitting BB and are about to emit NEXT_BB if non-NULL,
1319 or we are about to finish emiting code, if it is NULL. If the fall through
1320 edge from BB does not lead to NEXT_BB, emit an unconditional jump. */
1322 static void
1323 perhaps_emit_branch (basic_block bb, basic_block next_bb)
1325 basic_block t_bb = NULL, ff = NULL;
1326 struct BrigInstBr repr;
1327 BrigOperandOffset32_t operand_offsets[1];
1328 uint32_t byteCount;
1330 edge_iterator ei;
1331 edge e;
1333 FOR_EACH_EDGE (e, ei, bb->succs)
1334 if (e->flags & EDGE_TRUE_VALUE)
1336 gcc_assert (!t_bb);
1337 t_bb = e->dest;
1339 else
1341 gcc_assert (!ff);
1342 ff = e->dest;
1344 gcc_assert (ff);
1345 if (ff == next_bb
1346 || ff == EXIT_BLOCK_PTR_FOR_FN (cfun))
1347 return;
1349 repr.base.base.byteCount = htole16 (sizeof (repr));
1350 repr.base.base.kind = htole16 (BRIG_KIND_INST_BR);
1351 repr.base.opcode = htole16 (BRIG_OPCODE_BR);
1352 repr.base.type = htole16 (BRIG_TYPE_NONE);
1353 /* Direct branches to labels must be width(all). */
1354 repr.width = BRIG_WIDTH_ALL;
1356 operand_offsets[0] = htole32 (enqueue_op (&hsa_bb_for_bb (ff)->label_ref));
1357 /* We have 1 operand so use 4 * 1 for the byteCount */
1358 byteCount = htole32 (4 * 1);
1359 repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
1360 brig_data.add (&operand_offsets, sizeof (operand_offsets));
1361 brig_data.round_size_up (4);
1362 memset (&repr.reserved, 0, sizeof (repr.reserved));
1363 brig_code.add (&repr, sizeof (repr));
1364 brig_insn_count++;
1367 /* Emit the a function with name NAME to the various brig sections. */
1369 void
1370 hsa_brig_emit_function (void)
1372 basic_block bb, prev_bb;
1373 hsa_insn_basic *insn;
1374 BrigDirectiveExecutable *ptr_to_fndir;
1376 brig_init ();
1378 brig_insn_count = 0;
1379 memset (&op_queue, 0, sizeof (op_queue));
1380 op_queue.projected_size = brig_operand.total_size;
1382 ptr_to_fndir = emit_function_directives ();
1383 for (insn = hsa_bb_for_bb (ENTRY_BLOCK_PTR_FOR_FN (cfun))->first_insn;
1384 insn;
1385 insn = insn->next)
1386 emit_insn (insn);
1387 prev_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
1388 FOR_EACH_BB_FN (bb, cfun)
1390 perhaps_emit_branch (prev_bb, bb);
1391 emit_bb_label_directive (hsa_bb_for_bb (bb));
1392 for (insn = hsa_bb_for_bb (bb)->first_insn; insn; insn = insn->next)
1393 emit_insn (insn);
1394 prev_bb = bb;
1396 perhaps_emit_branch (prev_bb, NULL);
1397 ptr_to_fndir->codeBlockEntryCount = brig_insn_count ;
1398 ptr_to_fndir->nextModuleEntry = brig_code.total_size;
1400 emit_queued_operands ();
1403 void
1404 hsa_output_brig (void)
1406 section *saved_section;
1408 if (!brig_initialized)
1409 return;
1411 saved_section = in_section;
1413 brig_data.output ();
1414 brig_code.output ();
1415 brig_operand.output ();
1417 if (saved_section)
1418 switch_to_section (saved_section);
1420 brig_release_data ();
1421 hsa_deinit_compilation_unit_data ();