mirror of
https://github.com/tiagovignatti/intel-gpu-tools.git
synced 2025-06-10 01:16:18 +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,
|
static void set_direct_src_operand(struct src_operand *src, struct brw_reg *reg,
|
||||||
int type);
|
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 {
|
enum message_level {
|
||||||
WARN,
|
WARN,
|
||||||
ERROR,
|
ERROR,
|
||||||
@ -3152,3 +3155,83 @@ static void set_direct_src_operand(struct src_operand *src, struct brw_reg *reg,
|
|||||||
src->reg.abs = 0;
|
src->reg.abs = 0;
|
||||||
SWIZZLE(src->reg) = BRW_SWIZZLE_NOOP;
|
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"
|
#include "brw_eu.h"
|
||||||
|
|
||||||
extern FILE *yyin;
|
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;
|
long int gen_level = 40;
|
||||||
int advanced_flag = 0; /* 0: in unit of byte, 1: in unit of data element size */
|
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 }
|
{ 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)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "usage: intel-gen4asm [options] inputfile\n");
|
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) {
|
for (entry = compiled_program.first; entry; entry = entry->next) {
|
||||||
struct relocation *reloc = &entry->reloc;
|
struct relocation *reloc = &entry->reloc;
|
||||||
struct brw_instruction *inst = &entry->insn.gen;
|
|
||||||
|
|
||||||
if (!is_relocatable(entry))
|
if (!is_relocatable(entry))
|
||||||
continue;
|
continue;
|
||||||
@ -449,43 +440,10 @@ int main(int argc, char **argv)
|
|||||||
if (reloc->second_reloc_target)
|
if (reloc->second_reloc_target)
|
||||||
reloc->second_reloc_offset = label_to_addr(reloc->second_reloc_target, entry->inst_offset) - entry->inst_offset;
|
reloc->second_reloc_offset = label_to_addr(reloc->second_reloc_target, entry->inst_offset) - entry->inst_offset;
|
||||||
|
|
||||||
if (reloc->second_reloc_offset) {
|
if (reloc->second_reloc_offset) { // this is a branch instruction with two offset arguments
|
||||||
// this is a branch instruction with two offset arguments
|
set_branch_two_offsets(entry, reloc->first_reloc_offset, reloc->second_reloc_offset);
|
||||||
inst->bits3.break_cont.jip = jump_distance(reloc->first_reloc_offset);
|
|
||||||
inst->bits3.break_cont.uip = jump_distance(reloc->second_reloc_offset);
|
|
||||||
} else if (reloc->first_reloc_offset) {
|
} else if (reloc->first_reloc_offset) {
|
||||||
// this is a branch instruction with one offset argument
|
set_branch_one_offset(entry, reloc->first_reloc_offset);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user