From patchwork Mon Feb 4 15:27:33 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Lespiau, Damien" X-Patchwork-Id: 2093021 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id 197DDDFE82 for ; Mon, 4 Feb 2013 15:48:44 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 06F91E614C for ; Mon, 4 Feb 2013 07:48:44 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id B9C28E60D0 for ; Mon, 4 Feb 2013 07:29:33 -0800 (PST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 04 Feb 2013 07:29:33 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.84,600,1355126400"; d="scan'208";a="257441914" Received: from unknown (HELO dyon.amr.corp.intel.com) ([10.255.12.132]) by orsmga001.jf.intel.com with ESMTP; 04 Feb 2013 07:29:32 -0800 From: Damien Lespiau To: intel-gfx@lists.freedesktop.org Date: Mon, 4 Feb 2013 15:27:33 +0000 Message-Id: <1359991705-5254-39-git-send-email-damien.lespiau@intel.com> X-Mailer: git-send-email 1.7.7.5 In-Reply-To: <1359991705-5254-1-git-send-email-damien.lespiau@intel.com> References: <1359991705-5254-1-git-send-email-damien.lespiau@intel.com> Subject: [Intel-gfx] [PATCH 38/90] assembler: Make explicit that labels are part of the instructions list X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org The output of the parsing is a list of struct brw_program_instruction. These instructions can be either GEN instructions aka struct brw_instruction or labels. To make this more explicit we now have a type to test to determine which instruction we are dealing with. This will also allow to to pull the relocation bits into struct brw_program_instruction instead of having them in the structure representing the opcodes. Signed-off-by: Damien Lespiau --- assembler/disasm-main.c | 2 +- assembler/gen4asm.h | 36 +++++++++++++++++++++---- assembler/gram.y | 7 +++-- assembler/main.c | 66 +++++++++++++++++++++++++++-------------------- 4 files changed, 73 insertions(+), 38 deletions(-) diff --git a/assembler/disasm-main.c b/assembler/disasm-main.c index b900e91..fbb6ae3 100644 --- a/assembler/disasm-main.c +++ b/assembler/disasm-main.c @@ -167,6 +167,6 @@ int main(int argc, char **argv) } for (inst = program->first; inst; inst = inst->next) - brw_disasm (output, &inst->instruction, gen); + brw_disasm (output, &inst->instruction.gen, gen); exit (0); } diff --git a/assembler/gen4asm.h b/assembler/gen4asm.h index a2ab5e8..aa380e1 100644 --- a/assembler/gen4asm.h +++ b/assembler/gen4asm.h @@ -30,6 +30,8 @@ #define __GEN4ASM_H__ #include +#include +#include typedef unsigned char GLubyte; typedef short GLshort; @@ -133,18 +135,40 @@ typedef struct { } u; } imm32_t; +enum assembler_instruction_type { + GEN4ASM_INSTRUCTION_GEN, + GEN4ASM_INSTRUCTION_LABEL, +}; + +struct label_instruction { + char *name; +}; + /** * This structure is just the list container for instructions accumulated by * the parser and labels. */ struct brw_program_instruction { - struct brw_instruction instruction; - struct brw_program_instruction *next; - GLuint islabel; - GLuint inst_offset; - char *string; + enum assembler_instruction_type type; + unsigned inst_offset; + union { + struct brw_instruction gen; + struct label_instruction label; + } instruction; + struct brw_program_instruction *next; }; +static inline bool is_label(struct brw_program_instruction *instruction) +{ + return instruction->type == GEN4ASM_INSTRUCTION_LABEL; +} + +static inline char *label_name(struct brw_program_instruction *i) +{ + assert(is_label(i)); + return i->instruction.label.name; +} + /** * This structure is a list of instructions. It is the final output of the * parser. @@ -188,7 +212,7 @@ struct declared_register { }; struct declared_register *find_register(char *name); void insert_register(struct declared_register *reg); -void add_label(char *name, int addr); +void add_label(struct brw_program_instruction *instruction); int label_to_addr(char *name, int start_addr); int yyparse(void); diff --git a/assembler/gram.y b/assembler/gram.y index a1c09f7..cf65f9f 100644 --- a/assembler/gram.y +++ b/assembler/gram.y @@ -119,7 +119,8 @@ static void brw_program_add_instruction(struct brw_program *p, struct brw_program_instruction *list_entry; list_entry = calloc(sizeof(struct brw_program_instruction), 1); - list_entry->instruction = *instruction; + list_entry->type = GEN4ASM_INSTRUCTION_GEN; + list_entry->instruction.gen = *instruction; brw_program_append_entry(p, list_entry); } @@ -128,8 +129,8 @@ static void brw_program_add_label(struct brw_program *p, const char *label) struct brw_program_instruction *list_entry; list_entry = calloc(sizeof(struct brw_program_instruction), 1); - list_entry->string = strdup(label); - list_entry->islabel = 1; + list_entry->type = GEN4ASM_INSTRUCTION_LABEL; + list_entry->instruction.label.name = strdup(label); brw_program_append_entry(p, list_entry); } diff --git a/assembler/main.c b/assembler/main.c index 28daf3e..eb75230 100644 --- a/assembler/main.c +++ b/assembler/main.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "gen4asm.h" @@ -154,14 +155,17 @@ void insert_register(struct declared_register *reg) insert_hash_item(declared_register_table, reg->name, reg); } -void add_label(char *name, int addr) +void add_label(struct brw_program_instruction *i) { struct label_item **p = &label_table; + + assert(is_label(i)); + while(*p) p = &((*p)->next); *p = calloc(1, sizeof(**p)); - (*p)->name = name; - (*p)->addr = addr; + (*p)->name = label_name(i); + (*p)->addr = i->inst_offset; } /* Some assembly code have duplicated labels. @@ -220,11 +224,14 @@ static int read_entry_file(char *fn) return 0; } -static int is_entry_point(char *s) +static int is_entry_point(struct brw_program_instruction *i) { struct entry_point_item *p; + + assert(i->type == GEN4ASM_INSTRUCTION_LABEL); + for (p = entry_point_table; p; p = p->next) { - if (strcmp(p->str, s) == 0) + if (strcmp(p->str, i->instruction.label.name) == 0) return 1; } return 0; @@ -379,24 +386,24 @@ int main(int argc, char **argv) entry != NULL; entry = entry->next) { entry->inst_offset = inst_offset; entry1 = entry->next; - if (entry1 && entry1->islabel && is_entry_point(entry1->string)) { + if (entry1 && is_label(entry1) && is_entry_point(entry1)) { // insert NOP instructions until (inst_offset+1) % 4 == 0 while (((inst_offset+1) % 4) != 0) { tmp_entry = calloc(sizeof(*tmp_entry), 1); - tmp_entry->instruction.header.opcode = BRW_OPCODE_NOP; + tmp_entry->instruction.gen.header.opcode = BRW_OPCODE_NOP; entry->next = tmp_entry; tmp_entry->next = entry1; entry = tmp_entry; tmp_entry->inst_offset = ++inst_offset; } } - if (!entry->islabel) + if (!is_label(entry)) inst_offset++; } for (entry = compiled_program.first; entry; entry = entry->next) - if (entry->islabel) - add_label(entry->string, entry->inst_offset); + if (is_label(entry)) + add_label(entry); if (need_export) { if (export_filename) { @@ -406,15 +413,18 @@ int main(int argc, char **argv) } for (entry = compiled_program.first; entry != NULL; entry = entry->next) { - if (entry->islabel) + if (is_label(entry)) fprintf(export_file, "#define %s_IP %d\n", - entry->string, (IS_GENx(5) ? 2 : 1)*(entry->inst_offset)); + label_name(entry), (IS_GENx(5) ? 2 : 1)*(entry->inst_offset)); } fclose(export_file); } for (entry = compiled_program.first; entry; entry = entry->next) { - struct brw_instruction *inst = & entry->instruction; + struct brw_instruction *inst = & entry->instruction.gen; + + if (is_label(entry)) + continue; if (inst->first_reloc_target) inst->first_reloc_offset = label_to_addr(inst->first_reloc_target, entry->inst_offset) - entry->inst_offset; @@ -424,14 +434,14 @@ int main(int argc, char **argv) if (inst->second_reloc_offset) { // this is a branch instruction with two offset arguments - entry->instruction.bits3.break_cont.jip = jump_distance(inst->first_reloc_offset); - entry->instruction.bits3.break_cont.uip = jump_distance(inst->second_reloc_offset); + inst->bits3.break_cont.jip = jump_distance(inst->first_reloc_offset); + inst->bits3.break_cont.uip = jump_distance(inst->second_reloc_offset); } else if (inst->first_reloc_offset) { // this is a branch instruction with one offset argument int offset = inst->first_reloc_offset; /* bspec: Unlike other flow control instructions, the offset used by JMPI is relative to the incremented instruction pointer rather than the IP value for the instruction itself. */ - int is_jmpi = entry->instruction.header.opcode == BRW_OPCODE_JMPI; // target relative to the post-incremented IP, so delta == 1 if JMPI + int is_jmpi = inst->header.opcode == BRW_OPCODE_JMPI; // target relative to the post-incremented IP, so delta == 1 if JMPI if(is_jmpi) offset --; offset = jump_distance(offset); @@ -439,25 +449,25 @@ int main(int argc, char **argv) offset = offset * 8; if(!IS_GENp(6)) { - entry->instruction.bits3.JIP = offset; - if(entry->instruction.header.opcode == BRW_OPCODE_ELSE) - entry->instruction.bits3.break_cont.uip = 1; /* Set the istack pop count, which must always be 1. */ + inst->bits3.JIP = offset; + if(inst->header.opcode == BRW_OPCODE_ELSE) + inst->bits3.break_cont.uip = 1; /* Set the istack pop count, which must always be 1. */ } else if(IS_GENx(6)) { /* TODO: endif JIP pos is not in Gen6 spec. may be bits1 */ - int opcode = entry->instruction.header.opcode; + int opcode = inst->header.opcode; if(opcode == BRW_OPCODE_CALL || opcode == BRW_OPCODE_JMPI) - entry->instruction.bits3.JIP = offset; // for CALL, JMPI + inst->bits3.JIP = offset; // for CALL, JMPI else - entry->instruction.bits1.branch_gen6.jump_count = offset; // for CASE,ELSE,FORK,IF,WHILE + inst->bits1.branch_gen6.jump_count = offset; // for CASE,ELSE,FORK,IF,WHILE } else if(IS_GENp(7)) { - int opcode = entry->instruction.header.opcode; + int opcode = inst->header.opcode; /* Gen7 JMPI Restrictions in bspec: * The JIP data type must be Signed DWord */ if(opcode == BRW_OPCODE_JMPI) - entry->instruction.bits3.JIP = offset; + inst->bits3.JIP = offset; else - entry->instruction.bits3.break_cont.jip = offset; + inst->bits3.break_cont.jip = offset; } } } @@ -469,10 +479,10 @@ int main(int argc, char **argv) entry != NULL; entry = entry1) { entry1 = entry->next; - if (!entry->islabel) - print_instruction(output, &entry->instruction); + if (!is_label(entry)) + print_instruction(output, &entry->instruction.gen); else - free(entry->string); + free(entry->instruction.label.name); free(entry); } if (binary_like_output)