From 03fbff1efcccc0e09fc218c24b29e6d1ad4d4599 Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Thu, 13 Jun 2019 17:26:02 +0300 Subject: [PATCH] intel/assembler: Add labels support Use labels instead of numeric JIP/UIP offsets. Works for gen6+. v2: - Change asm tests to use labels on gen6+ - Remove usage of relative offsets on gen6+ - Consider brw_jump_scale when setting relative offset - Return error if there is a JIP/UIP label without matching target - Fix matching of label tokens Signed-off-by: Danylo Piliaiev Reviewed-by: Sagar Ghuge Reviewed-by: Matt Turner Part-of: --- src/intel/tools/i965_asm.c | 92 +++++ src/intel/tools/i965_asm.h | 24 ++ src/intel/tools/i965_gram.y | 356 ++++++++++++-------- src/intel/tools/i965_lex.l | 20 +- src/intel/tools/tests/gen6/break.asm | 15 +- src/intel/tools/tests/gen6/break.expected | 12 +- src/intel/tools/tests/gen6/cont.asm | 9 +- src/intel/tools/tests/gen6/cont.expected | 6 +- src/intel/tools/tests/gen6/else.asm | 7 +- src/intel/tools/tests/gen6/else.expected | 6 +- src/intel/tools/tests/gen6/endif.asm | 9 +- src/intel/tools/tests/gen6/halt.asm | 10 +- src/intel/tools/tests/gen6/halt.expected | 4 +- src/intel/tools/tests/gen6/if.asm | 14 +- src/intel/tools/tests/gen6/if.expected | 12 +- src/intel/tools/tests/gen6/while.asm | 13 +- src/intel/tools/tests/gen6/while.expected | 12 +- src/intel/tools/tests/gen7.5/break.asm | 14 +- src/intel/tools/tests/gen7.5/break.expected | 12 +- src/intel/tools/tests/gen7.5/cont.asm | 9 +- src/intel/tools/tests/gen7.5/cont.expected | 6 +- src/intel/tools/tests/gen7.5/else.asm | 7 +- src/intel/tools/tests/gen7.5/else.expected | 6 +- src/intel/tools/tests/gen7.5/endif.asm | 8 +- src/intel/tools/tests/gen7.5/endif.expected | 4 +- src/intel/tools/tests/gen7.5/halt.asm | 10 +- src/intel/tools/tests/gen7.5/halt.expected | 4 +- src/intel/tools/tests/gen7.5/if.asm | 15 +- src/intel/tools/tests/gen7.5/if.expected | 12 +- src/intel/tools/tests/gen7.5/while.asm | 13 +- src/intel/tools/tests/gen7.5/while.expected | 12 +- src/intel/tools/tests/gen7/break.asm | 15 +- src/intel/tools/tests/gen7/break.expected | 12 +- src/intel/tools/tests/gen7/else.asm | 7 +- src/intel/tools/tests/gen7/else.expected | 6 +- src/intel/tools/tests/gen7/endif.asm | 9 +- src/intel/tools/tests/gen7/halt.asm | 10 +- src/intel/tools/tests/gen7/halt.expected | 4 +- src/intel/tools/tests/gen7/if.asm | 15 +- src/intel/tools/tests/gen7/if.expected | 12 +- src/intel/tools/tests/gen7/while.asm | 11 +- src/intel/tools/tests/gen7/while.expected | 10 +- src/intel/tools/tests/gen8/break.asm | 10 +- src/intel/tools/tests/gen8/break.expected | 8 +- src/intel/tools/tests/gen8/cont.asm | 6 +- src/intel/tools/tests/gen8/cont.expected | 4 +- src/intel/tools/tests/gen8/else.asm | 7 +- src/intel/tools/tests/gen8/else.expected | 6 +- src/intel/tools/tests/gen8/endif.asm | 7 +- src/intel/tools/tests/gen8/endif.expected | 4 +- src/intel/tools/tests/gen8/halt.asm | 10 +- src/intel/tools/tests/gen8/halt.expected | 4 +- src/intel/tools/tests/gen8/if.asm | 12 +- src/intel/tools/tests/gen8/if.expected | 10 +- src/intel/tools/tests/gen8/while.asm | 9 +- src/intel/tools/tests/gen8/while.expected | 8 +- src/intel/tools/tests/gen9/break.asm | 10 +- src/intel/tools/tests/gen9/break.expected | 8 +- src/intel/tools/tests/gen9/cont.asm | 6 +- src/intel/tools/tests/gen9/cont.expected | 4 +- src/intel/tools/tests/gen9/else.asm | 7 +- src/intel/tools/tests/gen9/else.expected | 6 +- src/intel/tools/tests/gen9/endif.asm | 7 +- src/intel/tools/tests/gen9/endif.expected | 4 +- src/intel/tools/tests/gen9/halt.asm | 10 +- src/intel/tools/tests/gen9/halt.expected | 4 +- src/intel/tools/tests/gen9/if.asm | 12 +- src/intel/tools/tests/gen9/if.expected | 10 +- src/intel/tools/tests/gen9/while.asm | 9 +- src/intel/tools/tests/gen9/while.expected | 8 +- 70 files changed, 673 insertions(+), 401 deletions(-) diff --git a/src/intel/tools/i965_asm.c b/src/intel/tools/i965_asm.c index 1e6e0904b50..2be74e375d4 100644 --- a/src/intel/tools/i965_asm.c +++ b/src/intel/tools/i965_asm.c @@ -38,6 +38,9 @@ static enum opt_output_type output_type = OPT_OUTPUT_BIN; char *input_filename = NULL; int errors; +struct list_head instr_labels; +struct list_head target_labels; + static void print_help(const char *progname, FILE *file) { @@ -119,6 +122,90 @@ i965_disasm_init(uint16_t pci_id) return devinfo; } +static bool +i965_postprocess_labels() +{ + if (p->devinfo->gen < 6) { + return true; + } + + void *store = p->store; + + struct target_label *tlabel; + struct instr_label *ilabel, *s; + + const unsigned to_bytes_scale = brw_jump_scale(p->devinfo); + + LIST_FOR_EACH_ENTRY(tlabel, &target_labels, link) { + LIST_FOR_EACH_ENTRY_SAFE(ilabel, s, &instr_labels, link) { + if (!strcmp(tlabel->name, ilabel->name)) { + brw_inst *inst = store + ilabel->offset; + + int relative_offset = (tlabel->offset - ilabel->offset) / sizeof(brw_inst); + relative_offset *= to_bytes_scale; + + unsigned opcode = brw_inst_opcode(p->devinfo, inst); + + if (ilabel->type == INSTR_LABEL_JIP) { + switch (opcode) { + case BRW_OPCODE_IF: + case BRW_OPCODE_ELSE: + case BRW_OPCODE_ENDIF: + case BRW_OPCODE_WHILE: + if (p->devinfo->gen >= 7) { + brw_inst_set_jip(p->devinfo, inst, relative_offset); + } else if (p->devinfo->gen == 6) { + brw_inst_set_gen6_jump_count(p->devinfo, inst, relative_offset); + } + break; + case BRW_OPCODE_BREAK: + case BRW_OPCODE_HALT: + case BRW_OPCODE_CONTINUE: + brw_inst_set_jip(p->devinfo, inst, relative_offset); + break; + default: + fprintf(stderr, "Unknown opcode %d with JIP label\n", opcode); + return false; + } + } else { + switch (opcode) { + case BRW_OPCODE_IF: + case BRW_OPCODE_ELSE: + if (p->devinfo->gen > 7) { + brw_inst_set_uip(p->devinfo, inst, relative_offset); + } else if (p->devinfo->gen == 7) { + brw_inst_set_uip(p->devinfo, inst, relative_offset); + } else if (p->devinfo->gen == 6) { + // Nothing + } + break; + case BRW_OPCODE_WHILE: + case BRW_OPCODE_ENDIF: + fprintf(stderr, "WHILE/ENDIF cannot have UIP offset\n"); + return false; + case BRW_OPCODE_BREAK: + case BRW_OPCODE_CONTINUE: + case BRW_OPCODE_HALT: + brw_inst_set_uip(p->devinfo, inst, relative_offset); + break; + default: + fprintf(stderr, "Unknown opcode %d with UIP label\n", opcode); + return false; + } + } + + list_del(&ilabel->link); + } + } + } + + LIST_FOR_EACH_ENTRY(ilabel, &instr_labels, link) { + fprintf(stderr, "Unknown label '%s'\n", ilabel->name); + } + + return list_is_empty(&instr_labels); +} + int main(int argc, char **argv) { char *output_file = NULL; @@ -132,6 +219,8 @@ int main(int argc, char **argv) struct disasm_info *disasm_info; struct gen_device_info *devinfo = NULL; int result = EXIT_FAILURE; + list_inithead(&instr_labels); + list_inithead(&target_labels); const struct option i965_asm_opts[] = { { "help", no_argument, (int *) &help, true }, @@ -230,6 +319,9 @@ int main(int argc, char **argv) if (err || errors) goto end; + if (!i965_postprocess_labels()) + goto end; + store = p->store; disasm_info = disasm_initialize(p->devinfo, NULL); diff --git a/src/intel/tools/i965_asm.h b/src/intel/tools/i965_asm.h index dd29208198f..a7e4e86b36d 100644 --- a/src/intel/tools/i965_asm.h +++ b/src/intel/tools/i965_asm.h @@ -35,6 +35,7 @@ #include "compiler/brw_inst.h" #include "compiler/brw_eu.h" #include "dev/gen_device_info.h" +#include "util/list.h" /* glibc < 2.27 defines OVERFLOW in /usr/include/math.h. */ #undef OVERFLOW @@ -48,6 +49,9 @@ extern struct brw_codegen *p; extern int errors; extern char *input_filename; +extern struct list_head instr_labels; +extern struct list_head target_labels; + struct condition { unsigned cond_modifier:4; unsigned flag_reg_nr:1; @@ -77,4 +81,24 @@ struct options { unsigned is_compr:1; }; +enum instr_label_type { + INSTR_LABEL_JIP, + INSTR_LABEL_UIP, +}; + +struct instr_label { + struct list_head link; + + char *name; + int offset; + enum instr_label_type type; +}; + +struct target_label { + struct list_head link; + + char *name; + int offset; +}; + #endif /* __I965_ASM_H__ */ diff --git a/src/intel/tools/i965_gram.y b/src/intel/tools/i965_gram.y index 2b657688e25..e5fb2282703 100644 --- a/src/intel/tools/i965_gram.y +++ b/src/intel/tools/i965_gram.y @@ -310,6 +310,22 @@ i965_asm_set_dst_nr(struct brw_codegen *p, } } +static void +add_label(struct brw_codegen *p, const char* label_name, enum instr_label_type type) +{ + if (!label_name) { + return; + } + + struct instr_label *label = rzalloc(p->mem_ctx, struct instr_label); + + label->name = ralloc_strdup(p->mem_ctx, label_name); + label->offset = p->next_insn_offset; + label->type = type; + + list_addtail(&label->link, &instr_labels); +} + %} %locations @@ -317,6 +333,7 @@ i965_asm_set_dst_nr(struct brw_codegen *p, %start ROOT %union { + char *string; double number; int integer; unsigned long long int llint; @@ -350,6 +367,10 @@ i965_asm_set_dst_nr(struct brw_codegen *p, %token TYPE_DF TYPE_NF %token TYPE_VF +/* label */ +%token JUMP_LABEL +%token JUMP_LABEL_TARGET + /* opcodes */ %token ADD ADD3 ADDC AND ASR AVG %token BFE BFI1 BFI2 BFB BFREV BRC BRD BREAK @@ -502,6 +523,9 @@ i965_asm_set_dst_nr(struct brw_codegen *p, %type negate abs chansel math_function sharedfunction +%type jumplabeltarget +%type jumplabel + %code { static void @@ -608,6 +632,8 @@ instrseq: | instrseq relocatableinstruction SEMICOLON | instruction SEMICOLON | relocatableinstruction SEMICOLON + | instrseq jumplabeltarget + | jumplabeltarget ; /* Instruction Group */ @@ -1072,24 +1098,16 @@ jumpinstruction: /* branch instruction */ branchinstruction: - predicate ENDIF execsize relativelocation instoptions + predicate ENDIF execsize JUMP_LABEL instoptions { + add_label(p, $4, INSTR_LABEL_JIP); + brw_next_insn(p, $2); i965_asm_set_instruction_options(p, $5); brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); - if (p->devinfo->gen < 6) { - brw_set_dest(p, brw_last_inst, retype(brw_null_reg(), - BRW_REGISTER_TYPE_D)); - brw_set_src0(p, brw_last_inst, retype(brw_null_reg(), - BRW_REGISTER_TYPE_D)); - brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); - brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, - $4); - } else if (p->devinfo->gen == 6) { + if (p->devinfo->gen == 6) { brw_set_dest(p, brw_last_inst, brw_imm_w(0x0)); - brw_inst_set_gen6_jump_count(p->devinfo, brw_last_inst, - $4); brw_set_src0(p, brw_last_inst, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); brw_set_src1(p, brw_last_inst, retype(brw_null_reg(), @@ -1100,34 +1118,41 @@ branchinstruction: brw_set_src0(p, brw_last_inst, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); brw_set_src1(p, brw_last_inst, brw_imm_w(0x0)); - brw_inst_set_jip(p->devinfo, brw_last_inst, $4); } else { - brw_set_src0(p, brw_last_inst, brw_imm_d($4)); + brw_set_src0(p, brw_last_inst, brw_imm_d(0x0)); } - if (p->devinfo->gen < 6) - brw_inst_set_thread_control(p->devinfo, brw_last_inst, - BRW_THREAD_SWITCH); brw_pop_insn_state(p); } - | ELSE execsize relativelocation rellocation instoptions + | predicate ENDIF execsize relativelocation instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $5); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + + brw_set_dest(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src0(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); + brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, $4); + + brw_inst_set_thread_control(p->devinfo, brw_last_inst, + BRW_THREAD_SWITCH); + + brw_pop_insn_state(p); + } + | ELSE execsize JUMP_LABEL jumplabel instoptions { + add_label(p, $3, INSTR_LABEL_JIP); + add_label(p, $4, INSTR_LABEL_UIP); + brw_next_insn(p, $1); i965_asm_set_instruction_options(p, $5); brw_inst_set_exec_size(p->devinfo, brw_last_inst, $2); - if (p->devinfo->gen < 6) { - brw_set_dest(p, brw_last_inst, brw_ip_reg()); - brw_set_src0(p, brw_last_inst, brw_ip_reg()); - brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); - brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, - $3); - brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, - $4); - } else if (p->devinfo->gen == 6) { + if (p->devinfo->gen == 6) { brw_set_dest(p, brw_last_inst, brw_imm_w(0x0)); - brw_inst_set_gen6_jump_count(p->devinfo, brw_last_inst, - $3); brw_set_src0(p, brw_last_inst, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); brw_set_src1(p, brw_last_inst, retype(brw_null_reg(), @@ -1137,39 +1162,41 @@ branchinstruction: BRW_REGISTER_TYPE_D)); brw_set_src0(p, brw_last_inst, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); - brw_set_src1(p, brw_last_inst, brw_imm_w($3)); - brw_inst_set_jip(p->devinfo, brw_last_inst, $3); - brw_inst_set_uip(p->devinfo, brw_last_inst, $4); + brw_set_src1(p, brw_last_inst, brw_imm_w(0)); } else { brw_set_dest(p, brw_last_inst, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); - brw_set_src0(p, brw_last_inst, brw_imm_d($3)); - brw_inst_set_jip(p->devinfo, brw_last_inst, $3); - brw_inst_set_uip(p->devinfo, brw_last_inst, $4); + if (p->devinfo->gen < 12) + brw_set_src0(p, brw_last_inst, brw_imm_d(0)); } + } + | ELSE execsize relativelocation rellocation instoptions + { + brw_next_insn(p, $1); + i965_asm_set_instruction_options(p, $5); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $2); - if (!p->single_program_flow && p->devinfo->gen < 6) + brw_set_dest(p, brw_last_inst, brw_ip_reg()); + brw_set_src0(p, brw_last_inst, brw_ip_reg()); + brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); + brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, $3); + brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, $4); + + if (!p->single_program_flow) brw_inst_set_thread_control(p->devinfo, brw_last_inst, BRW_THREAD_SWITCH); } - | predicate IF execsize relativelocation rellocation instoptions + | predicate IF execsize JUMP_LABEL jumplabel instoptions { + add_label(p, $4, INSTR_LABEL_JIP); + add_label(p, $5, INSTR_LABEL_UIP); + brw_next_insn(p, $2); i965_asm_set_instruction_options(p, $6); brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); - if (p->devinfo->gen < 6) { - brw_set_dest(p, brw_last_inst, brw_ip_reg()); - brw_set_src0(p, brw_last_inst, brw_ip_reg()); - brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); - brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, - $4); - brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, - $5); - } else if (p->devinfo->gen == 6) { + if (p->devinfo->gen == 6) { brw_set_dest(p, brw_last_inst, brw_imm_w(0x0)); - brw_inst_set_gen6_jump_count(p->devinfo, brw_last_inst, - $4); brw_set_src0(p, brw_last_inst, vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_D))); @@ -1183,40 +1210,44 @@ branchinstruction: brw_set_src0(p, brw_last_inst, vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_D))); - brw_set_src1(p, brw_last_inst, brw_imm_w($4)); - brw_inst_set_jip(p->devinfo, brw_last_inst, $4); - brw_inst_set_uip(p->devinfo, brw_last_inst, $5); + brw_set_src1(p, brw_last_inst, brw_imm_w(0x0)); } else { brw_set_dest(p, brw_last_inst, vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_D))); - brw_set_src0(p, brw_last_inst, brw_imm_d($4)); - brw_inst_set_jip(p->devinfo, brw_last_inst, $4); - brw_inst_set_uip(p->devinfo, brw_last_inst, $5); + if (p->devinfo->gen < 12) + brw_set_src0(p, brw_last_inst, brw_imm_d(0x0)); } - if (!p->single_program_flow && p->devinfo->gen < 6) + brw_pop_insn_state(p); + } + | predicate IF execsize relativelocation rellocation instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $6); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + + brw_set_dest(p, brw_last_inst, brw_ip_reg()); + brw_set_src0(p, brw_last_inst, brw_ip_reg()); + brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); + brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, $4); + brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, $5); + + if (!p->single_program_flow) brw_inst_set_thread_control(p->devinfo, brw_last_inst, BRW_THREAD_SWITCH); brw_pop_insn_state(p); } - | predicate IFF execsize relativelocation instoptions + | predicate IFF execsize JUMP_LABEL instoptions { + add_label(p, $4, INSTR_LABEL_JIP); + brw_next_insn(p, $2); i965_asm_set_instruction_options(p, $5); brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); - if (p->devinfo->gen < 6) { - brw_set_dest(p, brw_last_inst, brw_ip_reg()); - brw_set_src0(p, brw_last_inst, brw_ip_reg()); - brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, - $4); - brw_set_src1(p, brw_last_inst, brw_imm_d($4)); - } else if (p->devinfo->gen == 6) { - brw_set_dest(p, brw_last_inst, brw_imm_w($4)); - brw_inst_set_gen6_jump_count(p->devinfo, brw_last_inst, - $4); + if (p->devinfo->gen == 6) { brw_set_src0(p, brw_last_inst, vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_D))); @@ -1230,17 +1261,29 @@ branchinstruction: brw_set_src0(p, brw_last_inst, vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_D))); - brw_set_src1(p, brw_last_inst, brw_imm_w($4)); - brw_inst_set_jip(p->devinfo, brw_last_inst, $4); + brw_set_src1(p, brw_last_inst, brw_imm_w(0x0)); } else { brw_set_dest(p, brw_last_inst, vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_D))); - brw_set_src0(p, brw_last_inst, brw_imm_d($4)); - brw_inst_set_jip(p->devinfo, brw_last_inst, $4); + if (p->devinfo->gen < 12) + brw_set_src0(p, brw_last_inst, brw_imm_d(0x0)); } - if (!p->single_program_flow && p->devinfo->gen < 6) + brw_pop_insn_state(p); + } + | predicate IFF execsize relativelocation instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $5); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + + brw_set_dest(p, brw_last_inst, brw_ip_reg()); + brw_set_src0(p, brw_last_inst, brw_ip_reg()); + brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, $4); + brw_set_src1(p, brw_last_inst, brw_imm_d($4)); + + if (!p->single_program_flow) brw_inst_set_thread_control(p->devinfo, brw_last_inst, BRW_THREAD_SWITCH); @@ -1250,8 +1293,11 @@ branchinstruction: /* break instruction */ breakinstruction: - predicate BREAK execsize relativelocation relativelocation instoptions + predicate BREAK execsize JUMP_LABEL JUMP_LABEL instoptions { + add_label(p, $4, INSTR_LABEL_JIP); + add_label(p, $5, INSTR_LABEL_UIP); + brw_next_insn(p, $2); i965_asm_set_instruction_options(p, $6); brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); @@ -1259,51 +1305,58 @@ breakinstruction: if (p->devinfo->gen >= 8) { brw_set_dest(p, brw_last_inst, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); - brw_set_src0(p, brw_last_inst, brw_imm_d($4)); - brw_inst_set_uip(p->devinfo, brw_last_inst, $5); - } else if (p->devinfo->gen >= 6) { + brw_set_src0(p, brw_last_inst, brw_imm_d(0x0)); + } else { brw_set_dest(p, brw_last_inst, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); brw_set_src0(p, brw_last_inst, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); - brw_inst_set_jip(p->devinfo, brw_last_inst, $4); - brw_inst_set_uip(p->devinfo, brw_last_inst, $5); - } else { - brw_set_dest(p, brw_last_inst, brw_ip_reg()); - brw_set_src0(p, brw_last_inst, brw_ip_reg()); - brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); - brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, - $4); - brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, - $5); } brw_pop_insn_state(p); } - | predicate HALT execsize relativelocation relativelocation instoptions + | predicate BREAK execsize relativelocation relativelocation instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $6); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + + brw_set_dest(p, brw_last_inst, brw_ip_reg()); + brw_set_src0(p, brw_last_inst, brw_ip_reg()); + brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); + brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, $4); + brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, $5); + + brw_pop_insn_state(p); + } + | predicate HALT execsize JUMP_LABEL JUMP_LABEL instoptions { + add_label(p, $4, INSTR_LABEL_JIP); + add_label(p, $5, INSTR_LABEL_UIP); + brw_next_insn(p, $2); i965_asm_set_instruction_options(p, $6); brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + brw_set_dest(p, brw_last_inst, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); if (p->devinfo->gen >= 8) { - brw_set_src0(p, brw_last_inst, brw_imm_d($4)); - brw_inst_set_uip(p->devinfo, brw_last_inst, $5); + brw_set_src0(p, brw_last_inst, brw_imm_d(0x0)); } else { brw_set_src0(p, brw_last_inst, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); - brw_set_src1(p, brw_last_inst, brw_imm_d($5)); + brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); } - brw_inst_set_jip(p->devinfo, brw_last_inst, $4); - brw_inst_set_uip(p->devinfo, brw_last_inst, $5); brw_pop_insn_state(p); } - | predicate CONT execsize relativelocation relativelocation instoptions + | predicate CONT execsize JUMP_LABEL JUMP_LABEL instoptions { + add_label(p, $4, INSTR_LABEL_JIP); + add_label(p, $5, INSTR_LABEL_UIP); + brw_next_insn(p, $2); i965_asm_set_instruction_options(p, $6); brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); @@ -1311,72 +1364,78 @@ breakinstruction: if (p->devinfo->gen >= 8) { brw_set_src0(p, brw_last_inst, brw_imm_d(0x0)); - brw_inst_set_jip(p->devinfo, brw_last_inst, $4); - brw_inst_set_uip(p->devinfo, brw_last_inst, $5); } else { brw_set_src0(p, brw_last_inst, brw_ip_reg()); brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); - if (p->devinfo->gen >= 6) { - brw_inst_set_jip(p->devinfo, brw_last_inst, $4); - brw_inst_set_uip(p->devinfo, brw_last_inst, $5); - } else { - brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, - $4); - brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, - $5); - } } brw_pop_insn_state(p); } + | predicate CONT execsize relativelocation relativelocation instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $6); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + brw_set_dest(p, brw_last_inst, brw_ip_reg()); + + brw_set_src0(p, brw_last_inst, brw_ip_reg()); + brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); + + brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, $4); + brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, $5); + + brw_pop_insn_state(p); + } ; /* loop instruction */ loopinstruction: - predicate WHILE execsize relativelocation instoptions + predicate WHILE execsize JUMP_LABEL instoptions { + add_label(p, $4, INSTR_LABEL_JIP); + brw_next_insn(p, $2); i965_asm_set_instruction_options(p, $5); brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); - if (p->devinfo->gen >= 6) { - if (p->devinfo->gen >= 8) { - brw_set_dest(p, brw_last_inst, - retype(brw_null_reg(), - BRW_REGISTER_TYPE_D)); - brw_set_src0(p, brw_last_inst, brw_imm_d($4)); - } else if (p->devinfo->gen == 7) { - brw_set_dest(p, brw_last_inst, - retype(brw_null_reg(), - BRW_REGISTER_TYPE_D)); - brw_set_src0(p, brw_last_inst, - retype(brw_null_reg(), - BRW_REGISTER_TYPE_D)); - brw_set_src1(p, brw_last_inst, - brw_imm_w(0x0)); - brw_inst_set_jip(p->devinfo, brw_last_inst, - $4); - } else { - brw_set_dest(p, brw_last_inst, brw_imm_w(0x0)); - brw_inst_set_gen6_jump_count(p->devinfo, - brw_last_inst, - $4); - brw_set_src0(p, brw_last_inst, - retype(brw_null_reg(), - BRW_REGISTER_TYPE_D)); - brw_set_src1(p, brw_last_inst, - retype(brw_null_reg(), - BRW_REGISTER_TYPE_D)); - } + if (p->devinfo->gen >= 8) { + brw_set_dest(p, brw_last_inst, + retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src0(p, brw_last_inst, brw_imm_d(0x0)); + } else if (p->devinfo->gen == 7) { + brw_set_dest(p, brw_last_inst, + retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src0(p, brw_last_inst, + retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src1(p, brw_last_inst, + brw_imm_w(0x0)); } else { - brw_set_dest(p, brw_last_inst, brw_ip_reg()); - brw_set_src0(p, brw_last_inst, brw_ip_reg()); - brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); - brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, - $4); - brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, - 0); + brw_set_dest(p, brw_last_inst, brw_imm_w(0x0)); + brw_set_src0(p, brw_last_inst, + retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src1(p, brw_last_inst, + retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); } + + brw_pop_insn_state(p); + } + | predicate WHILE execsize relativelocation instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $5); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + + brw_set_dest(p, brw_last_inst, brw_ip_reg()); + brw_set_src0(p, brw_last_inst, brw_ip_reg()); + brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); + brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, $4); + brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, 0); + brw_pop_insn_state(p); } | DO execsize instoptions @@ -1419,6 +1478,23 @@ relativelocation: } ; +jumplabel: + JUMP_LABEL { $$ = $1; } + | %empty { $$ = NULL; } + ; + +jumplabeltarget: + JUMP_LABEL_TARGET + { + struct target_label *label = rzalloc(p->mem_ctx, struct target_label); + + label->name = ralloc_strdup(p->mem_ctx, $1); + label->offset = p->next_insn_offset; + + list_addtail(&label->link, &target_labels); + } + ; + /* Destination register */ dst: dstoperand diff --git a/src/intel/tools/i965_lex.l b/src/intel/tools/i965_lex.l index 4e575a3253f..77986361123 100644 --- a/src/intel/tools/i965_lex.l +++ b/src/intel/tools/i965_lex.l @@ -24,6 +24,7 @@ extern char *input_filename; %x CHANNEL %x REG %x DOTSEL +%x LABEL %% /* eat up single line comment */ @@ -367,8 +368,8 @@ sr[0-9]+ { yylval.integer = atoi(yytext + 2); return STATEREG; } /* Eat up JIP and UIP token, their values will be parsed * in numeric section */ -"JIP: " { } -"UIP: " { } +"JIP: " { BEGIN(LABEL); } +"UIP: " { BEGIN(LABEL); } "Jump: " { } "Pop: " { } [ \t]+ { } @@ -383,6 +384,21 @@ sr[0-9]+ { yylval.integer = atoi(yytext + 2); return STATEREG; } return LONG; } + /* jump label target */ +[a-zA-Z_][0-9a-zA-Z_]*":" { + yylval.string = ralloc_strdup(p->mem_ctx, yytext); + /* Stomp the trailing ':' */ + yylval.string[yyleng - 1] = '\0'; + return JUMP_LABEL_TARGET; +} + + /* jump label */ +