Skip to content

Fragment asm: initial support of PSEQ fetch instruction and couple of minor changes #63

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/libgrate/fragment_asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,18 @@ typedef union fragment_alu_instruction_x4 {
} alu_instr;

typedef union fragment_pseq_instruction {
struct __attribute__((packed)) {
unsigned unk_0:1;
unsigned dst_regs_select:1;
unsigned unk_2:1;
unsigned enable0:1;
unsigned unk_4_15:12;
unsigned rt_select:4;
unsigned unk_20_22:3;
unsigned enable1:1;
unsigned unk_24_31:8;
};

uint32_t data;
} pseq_instr;

Expand Down
13 changes: 11 additions & 2 deletions src/libgrate/fragment_asm.l
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,14 @@ int yywrap(void)

%%
[ \t]+ /* skip */;
"/*"([^*]|(\*+[^*/]))*\*+\/ /* multi line comment */;
"/*"([^*]|(\*+[^*/]))*\*+\/ {
/* multi line comment */
unsigned i;

for (i = 0; i < strlen(yytext); i++)
if (yytext[i] == '\n')
yylineno++;
}
"//".* /* single line comment */;
[\n] yylineno++;

Expand Down Expand Up @@ -209,10 +216,12 @@ TXB return T_TXB_OPCODE;

rt[0-9]{1,2} {
fragment_asmlval.u = atoi(yytext + 2);
return T_DW_RENDER_TARGET;
return T_RENDER_TARGET;
}

"stencil" return T_DW_STENCIL;

FETCH return T_FETCH;

. return T_SYNTAX_ERROR;
%%
46 changes: 44 additions & 2 deletions src/libgrate/fragment_asm.y
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

%{
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -65,6 +66,8 @@ unsigned asm_pseq_to_dw_exec_nb;

int asm_discards_fragment;

static bool asm_alu_used[4];

static void reset_fragment_asm_parser_state(void)
{
int i, k;
Expand Down Expand Up @@ -94,6 +97,8 @@ static void reset_fragment_asm_parser_state(void)
asm_discards_fragment = 0;

fragment_asmlineno = 1;

memset(asm_alu_used, 0, sizeof(asm_alu_used));
}

static uint32_t float_to_fp20(float f)
Expand Down Expand Up @@ -228,7 +233,7 @@ static uint32_t float_to_fx10(float f)

%token T_DW_STORE
%token T_DW_STENCIL
%token <u> T_DW_RENDER_TARGET
%token <u> T_RENDER_TARGET

%token <u> T_HEX
%token <f> T_FLOAT
Expand Down Expand Up @@ -263,6 +268,8 @@ static uint32_t float_to_fx10(float f)
%token T_ALU_BUFFER_SIZE
%token T_PSEQ_DW_EXEC_NB

%token T_FETCH

%union {
char c;
float f;
Expand Down Expand Up @@ -481,6 +488,27 @@ PSEQ_INSTRUCTION:
asm_pseq_instructions[asm_fs_instructions_nb].data = $2;
}
|
T_PSEQ T_FETCH T_ROW_REGISTER ',' T_ROW_REGISTER ',' T_RENDER_TARGET
{
if ($3 == 0 && $5 == 1) {
asm_pseq_instructions[asm_fs_instructions_nb].dst_regs_select = 0;
}
else if ($3 == 2 && $5 == 3) {
asm_pseq_instructions[asm_fs_instructions_nb].dst_regs_select = 1;
}
else {
PARSE_ERROR("PSEQ destination registers should be either \"r0,r1\" or \"r2,r3\"");
}

if ($7 > 15) {
PARSE_ERROR("Invalid PSEQ render target, 15 is maximum");
}

asm_pseq_instructions[asm_fs_instructions_nb].rt_select = $7;
asm_pseq_instructions[asm_fs_instructions_nb].enable0 = 1;
asm_pseq_instructions[asm_fs_instructions_nb].enable1 = 1;
}
|
T_PSEQ T_OPCODE_NOP
|
;
Expand Down Expand Up @@ -831,6 +859,8 @@ ALU_INSTRUCTION: T_ALU ALUX_INSTRUCTIONS
asm_alu_sched[asm_fs_instructions_nb].instructions_nb++;
asm_alu_sched[asm_fs_instructions_nb].address = address;
asm_alu_instructions_nb++;

memset(asm_alu_used, 0, sizeof(asm_alu_used));
}
;

Expand All @@ -848,13 +878,25 @@ ALUX_INSTRUCTIONS:
ALUX_INSTRUCTION:
T_ALUX ALU_OPERATION
{
if (asm_alu_used[$1]) {
PARSE_ERROR("ALU has been overridden");
} else {
asm_alu_used[$1] = true;
}

asm_alu_instructions[asm_alu_instructions_nb].a[$1] = $2;
}
|
T_ALUX ALU3_IMMEDIATES
{
uint32_t swap = asm_alu_instructions[asm_alu_instructions_nb].part7;

if (asm_alu_used[$1]) {
PARSE_ERROR("ALU has been overridden");
} else {
asm_alu_used[$1] = true;
}

if ($1 != 3) {
PARSE_ERROR("ALU immediates can override ALU3 only");
}
Expand Down Expand Up @@ -1488,7 +1530,7 @@ DW_INSTRUCTION:
asm_dw_instructions[asm_fs_instructions_nb].data = $2;
}
|
T_DW T_DW_STORE T_DW_RENDER_TARGET ',' T_ROW_REGISTER ',' T_ROW_REGISTER
T_DW T_DW_STORE T_RENDER_TARGET ',' T_ROW_REGISTER ',' T_ROW_REGISTER
{
asm_dw_instructions[asm_fs_instructions_nb].enable = 1;

Expand Down
25 changes: 24 additions & 1 deletion src/libgrate/fragment_disasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,29 @@ static const char * disassemble_dw(const dw_instr *dw)
return ret;
}

static const char * disassemble_pseq(const pseq_instr *pseq)
{
static char ret[64];
char *buf = ret;

buf += sprintf(buf, "fetch ");

if (pseq->dst_regs_select) {
buf += sprintf(buf, "r2, r3, ");
} else {
buf += sprintf(buf, "r0, r1, ");
}

buf += sprintf(buf, "rt%u", pseq->rt_select);

if (pseq->unk_0 || pseq->unk_2 || pseq->unk_4_15 ||
pseq->unk_20_22 || pseq->unk_24_31) {
sprintf(buf, " // 0x%08X", pseq->data);
}

return ret;
}

const char * fragment_pipeline_disassemble(
const pseq_instr *pseq,
const mfu_instr *mfu, unsigned mfu_nb,
Expand All @@ -726,7 +749,7 @@ const char * fragment_pipeline_disassemble(
buf += sprintf(buf, "EXEC\n");

if (pseq->data != 0x00000000) {
buf += sprintf(buf, "\tPSEQ:\t0x%08X\n", pseq->data);
buf += sprintf(buf, "\tPSEQ:\t%s\n", disassemble_pseq(pseq));
}

for (i = 0; i < mfu_nb; i++) {
Expand Down
9 changes: 8 additions & 1 deletion src/libgrate/linker_asm.l
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,14 @@ int yywrap(void)

%%
[ \t]+ /* skip */;
"/*"([^*]|(\*+[^*/]))*\*+\/ /* multi line comment */;
"/*"([^*]|(\*+[^*/]))*\*+\/ {
/* multi line comment */
unsigned i;

for (i = 0; i < strlen(yytext); i++)
if (yytext[i] == '\n')
yylineno++;
}
"//".* /* single line comment */;
[\n] yylineno++;
"." return '.';
Expand Down
9 changes: 8 additions & 1 deletion src/libgrate/vertex_asm.l
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,14 @@ int yywrap(void)

%%
[ \t]+ /* skip */;
"/*"([^*]|(\*+[^*/]))*\*+\/ /* multi line comment */;
"/*"([^*]|(\*+[^*/]))*\*+\/ {
/* multi line comment */
unsigned i;

for (i = 0; i < strlen(yytext); i++)
if (yytext[i] == '\n')
yylineno++;
}
"//".* /* single line comment */;
[\n] yylineno++;

Expand Down