diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index ea24aabb56e..b46e3b9826d 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -305,6 +305,11 @@ static bool resolve_labels(void) return true; } +static unsigned cat6_type_shift() +{ + return util_logbase2(type_size(instr->cat6.type) / 8); +} + #ifdef YYDEBUG int yydebug; #endif @@ -782,7 +787,7 @@ static void print_token(FILE *file, int type, YYSTYPE value) %type cat4_opc %type cat5_opc cat5_samp cat5_tex cat5_type %type type -%type const_val +%type const_val cat6_src_shift %error-verbose @@ -1240,25 +1245,36 @@ cat6_dst_offset: offset { instr->cat6.dst_offset = $1; } cat6_immed: integer { instr->cat6.iim_val = $1; } -cat6_a6xx_global_address_pt3: - '<' '<' integer offset '<' '<' integer { - assert($7 == 2); - new_src(0, IR3_REG_IMMED)->uim_val = $3 - 2; - new_src(0, IR3_REG_IMMED)->uim_val = $4; - } -| '+' cat6_reg_or_immed { - // Dummy src to smooth the difference between a6xx and a7xx - new_src(0, IR3_REG_IMMED)->uim_val = 0; - } +cat6_src_shift: '<' '<' integer {$$ = $3;} +| {$$ = 0;} cat6_a6xx_global_address_pt2: - '(' src offset ')' '<' '<' integer { - assert($7 == 2); - new_src(0, IR3_REG_IMMED)->uim_val = 0; - new_src(0, IR3_REG_IMMED)->uim_val = $3; + '(' '(' '(' src cat6_src_shift ')' offset ')' '<' '<' integer ')' { + illegal_syntax_from(7, "pre-a7xx global offset syntax"); + new_src(0, IR3_REG_IMMED)->uim_val = $5; + new_src(0, IR3_REG_IMMED)->uim_val = $7; + } +| '(' '(' src cat6_src_shift offset ')' '<' '<' integer ')' { + illegal_syntax_from(7, "pre-a7xx global offset syntax"); + new_src(0, IR3_REG_IMMED)->uim_val = $4; + new_src(0, IR3_REG_IMMED)->uim_val = $5; + } +| '(' src cat6_src_shift ')' { + illegal_syntax_from(7, "pre-a7xx global offset syntax"); + // The shift contains the implicit type shift, subtract it. + new_src(0, IR3_REG_IMMED)->uim_val = $3 - cat6_type_shift(); + new_src(0, IR3_REG_IMMED)->uim_val = 0; + } +| src offset { + if (variant->compiler->gen < 7) { + new_src(0, IR3_REG_IMMED)->uim_val = 0; + new_src(0, IR3_REG_IMMED)->uim_val = $2; + } else { + new_src(0, IR3_REG_IMMED)->uim_val = $2; + // Dummy src to smooth the difference between a6xx and a7xx + new_src(0, IR3_REG_IMMED)->uim_val = 0; + } } - -| src cat6_a6xx_global_address_pt3 cat6_a6xx_global_address: src_reg_or_const '+' cat6_a6xx_global_address_pt2 diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index 6dbc4da5d6f..a0385ae6d8e 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -205,9 +205,9 @@ static const struct test { // TODO is this a real instruction? Or float -6.0 ? // INSTR_6XX(c0c00000_00000000, "stg.f16 g[hr0.x], hr0.x, hr0.x", .parse_fail=true), /* dEQP-GLES31.functional.tessellation.invariance.outer_edge_symmetry.isolines_equal_spacing_ccw */ - INSTR_6XX(c0d20906_02800004, "stg.a.f32 g[r1.x+(r1.z)<<2], r0.z, 2"), /* stg.a.f32 g[r1.x+(r1.z<<2)], r0.z, 2 */ - INSTR_6XX(c0da052e_01800042, "stg.a.s32 g[r0.z+(r11.z)<<2], r8.y, 1"), /* stg.a.s32 g[r0.z+(r11.z<<2)], r8.y, 1 */ - INSTR_6XX(c0dc052e_01800042, "stg.a.u8 g[r0.z+(r11.z)<<2], hr8.y, 1"), + INSTR_6XX(c0d20906_02800004, "stg.a.f32 g[r1.x+(r1.z<<2)], r0.z, 2"), + INSTR_6XX(c0da052e_01800042, "stg.a.s32 g[r0.z+(r11.z<<2)], r8.y, 1"), + INSTR_6XX(c0dc052e_01800042, "stg.a.u8 g[r0.z+r11.z], hr8.y, 1"), INSTR_6XX(c0ca0505_03800042, "stg.s32 g[r0.z+5], r8.y, 3"), INSTR_6XX(c0ca0500_03800042, "stg.s32 g[r0.z], r8.y, 3"), INSTR_6XX(c0ca0531_03800242, "stg.s32 g[r0.z+305], r8.y, 3"), @@ -220,30 +220,29 @@ static const struct test { INSTR_7XX(c0260207_00630100, "resbase.untyped.1d.u32.1.imm.base0 r1.w, 1"), /* resbase.u32.1d.mode4.base0 r1.w, 1 */ /* Customely crafted */ - INSTR_6XX(c0d61104_01800228, "stg.a.u32 g[r2.x+(r1.x+1)<<2], r5.x, 1"), - INSTR_6XX(c0d61104_01802628, "stg.a.u32 g[r2.x+r1.x<<4+3<<2], r5.x, 1"), + INSTR_6XX(c0d61104_01800228, "stg.a.u32 g[r2.x+((r1.x+1)<<2)], r5.x, 1"), + INSTR_6XX(c0d61104_01802628, "stg.a.u32 g[r2.x+(((r1.x<<2)+3)<<2)], r5.x, 1"), INSTR_7XX(c0d20505_07bfc006, "stg.a.f32 g[r0.z+r1.y+255], r0.w, 7"), INSTR_7XX(c0d20507_04812006, "stg.a.f32 g[c0.z+r1.w+4], r0.w, 4"), - INSTR_6XX(c0020011_04c08023, "ldg.a.f32 r4.y, g[r0.z+(r4.y)<<2], 4"), /* ldg.a.f32 r4.y, g[r0.z+(r4.y<<2)], 4 */ - INSTR_6XX(c0060006_01c18017, "ldg.a.u32 r1.z, g[r1.z+(r2.w)<<2], 1"), /* ldg.a.u32 r1.z, g[r1.z+(r2.w<<2)], 1 */ + INSTR_6XX(c0020011_04c08023, "ldg.a.f32 r4.y, g[r0.z+(r4.y<<2)], 4"), + INSTR_6XX(c0060006_01c18017, "ldg.a.u32 r1.z, g[r1.z+(r2.w<<2)], 1"), INSTR_6XX(c0060006_0181800f, "ldg.u32 r1.z, g[r1.z+7], 1"), INSTR_6XX(c0060006_01818001, "ldg.u32 r1.z, g[r1.z], 1"), INSTR_6XX(c0060003_0180c269, "ldg.u32 r0.w, g[r0.w+308], 1"), INSTR_6XX(c0040003_0180c269, "ldg.u16 hr0.w, g[r0.w+308], 1"), /* Found in TCS/TES shaders of GTA V */ - INSTR_6XX(c0020007_03c1420f, "ldg.a.f32 r1.w, g[r1.y+(r1.w+1)<<2], 3"), /* ldg.a.f32 r1.w, g[r1.y+((r1.w+1)<<2)], 3 */ + INSTR_6XX(c0020007_03c1420f, "ldg.a.f32 r1.w, g[r1.y+((r1.w+1)<<2)], 3"), /* Customely crafted */ - INSTR_6XX(c0020007_03c1740f, "ldg.a.f32 r1.w, g[r1.y+r1.w<<5+2<<2], 3"), + INSTR_6XX(c0020007_03c1740f, "ldg.a.f32 r1.w, g[r1.y+(((r1.w<<3)+2)<<2)], 3"), - INSTR_6XX(c0020011_04c08023, "ldg.a.f32 r4.y, g[r0.z+(r4.y)<<2], 4"), /* ldg.a.f32 r4.y, g[r0.z+(r4.y<<2)], 4 */ - INSTR_6XX(c0060006_01c18017, "ldg.a.u32 r1.z, g[r1.z+(r2.w)<<2], 1"), /* ldg.a.u32 r1.z, g[r1.z+(r2.w<<2)], 1 */ - INSTR_6XX(c0000006_01c18017, "ldg.a.f16 hr1.z, g[r1.z+(r2.w)<<2], 1"), + INSTR_6XX(c0000006_01c18017, "ldg.a.f16 hr1.z, g[r1.z+(r2.w<<1)], 1"), INSTR_6XX(c0060006_0181800f, "ldg.u32 r1.z, g[r1.z+7], 1"), INSTR_6XX(c0060006_01818001, "ldg.u32 r1.z, g[r1.z], 1"), + INSTR_6XX(c0060006_01c1b017, "ldg.a.u32 r1.z, g[r1.z+(r2.w<<5)], 1"), INSTR_7XX(c0020411_04c08023, "ldg.a.f32 r4.y, g[r0.z+r4.y+2], 4"), INSTR_7XX(c0004006_01c1a017, "ldg.a.f16 hr1.z, g[c1.z+r2.w+32], 1"), diff --git a/src/freedreno/isa/ir3-cat6.xml b/src/freedreno/isa/ir3-cat6.xml index d5b47122fb5..6d377c3998a 100644 --- a/src/freedreno/isa/ir3-cat6.xml +++ b/src/freedreno/isa/ir3-cat6.xml @@ -79,6 +79,14 @@ SOFTWARE. + + {TYPE} >= 6 ? 0 /* u8 */ : ({TYPE_HALF} ? 1 : 2); + + + + {TYPE_SHIFT} + {SRC2_SHIFT} + + 1 @@ -117,35 +125,64 @@ SOFTWARE. LoaD Global + + The 64b base address is stored in SRC1 (least significant bits) + and SRC1+1 (most significant bits). + + An offset is added to the base address that is calculated as + follows: + ((SRC2<<SRC2_SHIFT) + OFF)<<TYPE_SHIFT + + TYPE_SHIFT is implicitly given by the TYPE field; it ensures + that the offset is in units of the type. Note that non + type-aligned accesses are still supported if SRC1 is not + aligned. + + Note that although SRC2 is 32b, the calculation above does not + cause any 32b overflows: it behaves as if all values are + zero-extended to 64b first. - {SY}{JP}{NAME}.{TYPE} {TYPE_HALF}{DST}, g[{SRC1}+({SRC2}{OFF})<<{SRC2_BYTE_SHIFT}], {SIZE} + {SY}{JP}{NAME}.{TYPE} {TYPE_HALF}{DST}, g[{SRC1}+((({SRC2}<<{SRC2_SHIFT}){OFF})<<{TYPE_SHIFT})], {SIZE} - {SY}{JP}{NAME}.{TYPE} {TYPE_HALF}{DST}, g[{SRC1}+{SRC2}<<{SRC2_BYTE_SHIFT}{OFF}<<2], {SIZE} + {SY}{JP}{NAME}.{TYPE} {TYPE_HALF}{DST}, g[{SRC1}+{SRC2}{OFF}], {SIZE} - {SRC2_ADD_DWORD_SHIFT} > 0 + {TYPE_SHIFT} == 0 + + + + + {SY}{JP}{NAME}.{TYPE} {TYPE_HALF}{DST}, g[{SRC1}+({SRC2}<<{FULL_SHIFT})], {SIZE} + + {OFF} == 0 + + + + + {SY}{JP}{NAME}.{TYPE} {TYPE_HALF}{DST}, g[{SRC1}+(({SRC2}{OFF})<<{TYPE_SHIFT})], {SIZE} + + {SRC2_SHIFT} == 0 0 - + 1 xxxxxxxx - - {SRC2_ADD_DWORD_SHIFT} + 2 - + + src->srcs[1] - extract_reg_uim(src->srcs[2]) + extract_reg_uim(src->srcs[2]) extract_reg_uim(src->srcs[3]) extract_reg_uim(src->srcs[4]) @@ -260,28 +297,43 @@ SOFTWARE. STore Global + + See the doc of ldg.a for how the address is calculated. - {SY}{JP}{NAME}.{TYPE} g[{SRC1}+({SRC2}{OFF})<<{DST_BYTE_SHIFT}], {TYPE_HALF}{SRC3}, {SIZE} + {SY}{JP}{NAME}.{TYPE} g[{SRC1}+((({SRC2}<<{SRC2_SHIFT}){OFF})<<{TYPE_SHIFT})], {TYPE_HALF}{SRC3}, {SIZE} - {SY}{JP}{NAME}.{TYPE} g[{SRC1}+{SRC2}<<{DST_BYTE_SHIFT}{OFF}<<2], {TYPE_HALF}{SRC3}, {SIZE} + {SY}{JP}{NAME}.{TYPE} g[{SRC1}+{SRC2}{OFF}], {TYPE_HALF}{SRC3}, {SIZE} - {SRC2_ADD_DWORD_SHIFT} > 0 + {TYPE_SHIFT} == 0 - - {SRC2_ADD_DWORD_SHIFT} + 2 - + + + {SY}{JP}{NAME}.{TYPE} g[{SRC1}+({SRC2}<<{FULL_SHIFT})], {TYPE_HALF}{SRC3}, {SIZE} + + {OFF} == 0 + + + + + {SY}{JP}{NAME}.{TYPE} g[{SRC1}+(({SRC2}{OFF})<<{TYPE_SHIFT})], {TYPE_HALF}{SRC3}, {SIZE} + + {SRC2_SHIFT} == 0 + + + + 0 - + xxxxxxxx 1x @@ -289,7 +341,7 @@ SOFTWARE. src->srcs[1] - extract_reg_uim(src->srcs[2]) + extract_reg_uim(src->srcs[2]) extract_reg_uim(src->srcs[3]) src->srcs[4] extract_reg_uim(src->srcs[5])