mirror of
				https://github.com/tiagovignatti/intel-gpu-tools.git
				synced 2025-11-04 03:58:27 +00:00 
			
		
		
		
	assembler/bdw: Set jip/uip offsets used by flow control instructions
Signed-off-by: Xiang, Haihao <haihao.xiang@intel.com> Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
This commit is contained in:
		
							parent
							
								
									2df4d3115a
								
							
						
					
					
						commit
						216163b44d
					
				@ -117,6 +117,9 @@ static void set_direct_dst_operand(struct brw_reg *dst, struct brw_reg *reg,
 | 
			
		||||
static void set_direct_src_operand(struct src_operand *src, struct brw_reg *reg,
 | 
			
		||||
				   int type);
 | 
			
		||||
 | 
			
		||||
void set_branch_two_offsets(struct brw_program_instruction *insn, int jip_offset, int uip_offset);
 | 
			
		||||
void set_branch_one_offset(struct brw_program_instruction *insn, int jip_offset);
 | 
			
		||||
 | 
			
		||||
enum message_level {
 | 
			
		||||
    WARN,
 | 
			
		||||
    ERROR,
 | 
			
		||||
@ -3152,3 +3155,83 @@ static void set_direct_src_operand(struct src_operand *src, struct brw_reg *reg,
 | 
			
		||||
	src->reg.abs = 0;
 | 
			
		||||
	SWIZZLE(src->reg) = BRW_SWIZZLE_NOOP;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int instruction_opcode(struct brw_program_instruction *insn)
 | 
			
		||||
{
 | 
			
		||||
    if (IS_GENp(8))
 | 
			
		||||
	return gen8_opcode(GEN8(insn));
 | 
			
		||||
    else
 | 
			
		||||
	return GEN(insn)->header.opcode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * return the offset used in native flow control (branch) instructions
 | 
			
		||||
 */
 | 
			
		||||
static inline int branch_offset(struct brw_program_instruction *insn, int 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.
 | 
			
		||||
     */
 | 
			
		||||
    if (instruction_opcode(insn) == BRW_OPCODE_JMPI)
 | 
			
		||||
        offset--;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Gen4- bspec: the jump distance is in number of sixteen-byte units
 | 
			
		||||
     * Gen5+ bspec: the jump distance is in number of eight-byte units
 | 
			
		||||
     * Gen7.5+: the offset is in unit of 8bits for JMPI, 64bits for other flow
 | 
			
		||||
     * control instructions
 | 
			
		||||
     */
 | 
			
		||||
    if (gen_level >= 75 &&
 | 
			
		||||
        (instruction_opcode(insn) == BRW_OPCODE_JMPI))
 | 
			
		||||
        offset *= 16;
 | 
			
		||||
    else if (gen_level >= 50)
 | 
			
		||||
        offset *= 2;
 | 
			
		||||
 | 
			
		||||
    return offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_branch_two_offsets(struct brw_program_instruction *insn, int jip_offset, int uip_offset)
 | 
			
		||||
{
 | 
			
		||||
    int jip = branch_offset(insn, jip_offset);
 | 
			
		||||
    int uip = branch_offset(insn, uip_offset);
 | 
			
		||||
 | 
			
		||||
    assert(instruction_opcode(insn) != BRW_OPCODE_JMPI);
 | 
			
		||||
 | 
			
		||||
    if (IS_GENp(8)) {
 | 
			
		||||
        gen8_set_jip(GEN8(insn), jip);
 | 
			
		||||
	gen8_set_uip(GEN8(insn), uip);
 | 
			
		||||
    } else {
 | 
			
		||||
        GEN(insn)->bits3.break_cont.jip = jip;
 | 
			
		||||
        GEN(insn)->bits3.break_cont.uip = uip;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_branch_one_offset(struct brw_program_instruction *insn, int jip_offset)
 | 
			
		||||
{
 | 
			
		||||
    int jip = branch_offset(insn, jip_offset);
 | 
			
		||||
 | 
			
		||||
    if (IS_GENp(8)) {
 | 
			
		||||
        gen8_set_jip(GEN8(insn), jip);
 | 
			
		||||
    } else if (IS_GENx(7)) {
 | 
			
		||||
        /* Gen7 JMPI Restrictions in bspec:
 | 
			
		||||
         * The JIP data type must be Signed DWord
 | 
			
		||||
         */
 | 
			
		||||
        if (instruction_opcode(insn) == BRW_OPCODE_JMPI)
 | 
			
		||||
            GEN(insn)->bits3.JIP = jip;
 | 
			
		||||
        else
 | 
			
		||||
            GEN(insn)->bits3.break_cont.jip = jip;
 | 
			
		||||
    } else if (IS_GENx(6)) {
 | 
			
		||||
        if ((instruction_opcode(insn) == BRW_OPCODE_CALL) ||
 | 
			
		||||
            (instruction_opcode(insn) == BRW_OPCODE_JMPI))
 | 
			
		||||
            GEN(insn)->bits3.JIP = jip;
 | 
			
		||||
        else
 | 
			
		||||
            GEN(insn)->bits1.branch_gen6.jump_count = jip; // for CASE,ELSE,FORK,IF,WHILE
 | 
			
		||||
    } else {
 | 
			
		||||
        GEN(insn)->bits3.JIP = jip;
 | 
			
		||||
 | 
			
		||||
        if (instruction_opcode(insn) == BRW_OPCODE_ELSE)
 | 
			
		||||
            GEN(insn)->bits3.break_cont.uip = 1; // Set the istack pop count, which must always be 1.
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -38,6 +38,8 @@
 | 
			
		||||
#include "brw_eu.h"
 | 
			
		||||
 | 
			
		||||
extern FILE *yyin;
 | 
			
		||||
extern void set_branch_two_offsets(struct brw_program_instruction *insn, int jip_offset, int uip_offset);
 | 
			
		||||
extern void set_branch_one_offset(struct brw_program_instruction *insn, int jip_offset);
 | 
			
		||||
 | 
			
		||||
long int gen_level = 40;
 | 
			
		||||
int advanced_flag = 0; /* 0: in unit of byte, 1: in unit of data element size */
 | 
			
		||||
@ -86,16 +88,6 @@ static const struct option longopts[] = {
 | 
			
		||||
	{ NULL, 0, NULL, 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// jump distance used in branch instructions as JIP or UIP
 | 
			
		||||
static int jump_distance(int offset)
 | 
			
		||||
{
 | 
			
		||||
    // Gen4- bspec: the jump distance is in number of sixteen-byte units
 | 
			
		||||
    // Gen5+ bspec: the jump distance is in number of eight-byte units
 | 
			
		||||
    if(IS_GENp(5))
 | 
			
		||||
        offset *= 2;
 | 
			
		||||
    return offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void usage(void)
 | 
			
		||||
{
 | 
			
		||||
	fprintf(stderr, "usage: intel-gen4asm [options] inputfile\n");
 | 
			
		||||
@ -438,7 +430,6 @@ int main(int argc, char **argv)
 | 
			
		||||
 | 
			
		||||
	for (entry = compiled_program.first; entry; entry = entry->next) {
 | 
			
		||||
	    struct relocation *reloc = &entry->reloc;
 | 
			
		||||
	    struct brw_instruction *inst = &entry->insn.gen;
 | 
			
		||||
 | 
			
		||||
	    if (!is_relocatable(entry))
 | 
			
		||||
		continue;
 | 
			
		||||
@ -449,43 +440,10 @@ int main(int argc, char **argv)
 | 
			
		||||
	    if (reloc->second_reloc_target)
 | 
			
		||||
		reloc->second_reloc_offset = label_to_addr(reloc->second_reloc_target, entry->inst_offset) - entry->inst_offset;
 | 
			
		||||
 | 
			
		||||
	    if (reloc->second_reloc_offset) {
 | 
			
		||||
		// this is a branch instruction with two offset arguments
 | 
			
		||||
		inst->bits3.break_cont.jip = jump_distance(reloc->first_reloc_offset);
 | 
			
		||||
		inst->bits3.break_cont.uip = jump_distance(reloc->second_reloc_offset);
 | 
			
		||||
	    if (reloc->second_reloc_offset) { // this is a branch instruction with two offset arguments
 | 
			
		||||
                set_branch_two_offsets(entry, reloc->first_reloc_offset, reloc->second_reloc_offset);
 | 
			
		||||
	    } else if (reloc->first_reloc_offset) {
 | 
			
		||||
		// this is a branch instruction with one offset argument
 | 
			
		||||
		int offset = reloc->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 = 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);
 | 
			
		||||
		if (is_jmpi && (gen_level == 75))
 | 
			
		||||
			offset = offset * 8;
 | 
			
		||||
 | 
			
		||||
		if(!IS_GENp(6)) {
 | 
			
		||||
		    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 = inst->header.opcode;
 | 
			
		||||
		    if(opcode == BRW_OPCODE_CALL || opcode == BRW_OPCODE_JMPI)
 | 
			
		||||
			inst->bits3.JIP = offset; // for CALL, JMPI
 | 
			
		||||
		    else
 | 
			
		||||
			inst->bits1.branch_gen6.jump_count = offset; // for CASE,ELSE,FORK,IF,WHILE
 | 
			
		||||
		} else if(IS_GENp(7)) {
 | 
			
		||||
		    int opcode = inst->header.opcode;
 | 
			
		||||
		    /* Gen7 JMPI Restrictions in bspec:
 | 
			
		||||
		     * The JIP data type must be Signed DWord
 | 
			
		||||
		     */
 | 
			
		||||
		    if(opcode == BRW_OPCODE_JMPI)
 | 
			
		||||
			inst->bits3.JIP = offset;
 | 
			
		||||
		    else
 | 
			
		||||
			inst->bits3.break_cont.jip = offset;
 | 
			
		||||
		}
 | 
			
		||||
                set_branch_one_offset(entry, reloc->first_reloc_offset);
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user