From: H.J. Lu Date: Mon, 17 Sep 2018 16:33:20 +0000 (-0700) Subject: x86: Set EVex=2 on EVEX.128 only vmovd and vmovq X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=04e2a1829ea137ac23ac96e98fd60f9d720dcdcb;p=binutils-gdb.git x86: Set EVex=2 on EVEX.128 only vmovd and vmovq EVEX "VMOVD xmm1, r32/m32", "VMOVD r32/m32, xmm2", "VMOVQ xmm1, r64/m64", "VMOVD r64/m64, xmm2", "VMOVQ xmm1, xmm2/m64" and "VMOVQ xmm1/m64, xmm2" can only be encoded with EVEX.128. Set EVex=2 on EVEX.128 only vmovd and vmovq. gas/ PR gas/23670 * testsuite/gas/i386/evex-lig-2.d: New file. * testsuite/gas/i386/evex-lig-2.s: Likewise. * testsuite/gas/i386/x86-64-evex-lig-2.d: Likewise. * testsuite/gas/i386/x86-64-evex-lig-2.s: Likewise. * testsuite/gas/i386/i386.exp: Run evex-lig-2 and x86-64-evex-lig-2. opcodes/ PR gas/23670 * i386-dis-evex.h (evex_table): Use EVEX_LEN_0F6E_P_2, EVEX_LEN_0F7E_P_1, EVEX_LEN_0F7E_P_2 and EVEX_LEN_0FD6_P_2. (EVEX_LEN_0F6E_P_2): New EVEX_LEN_TABLE entry. (EVEX_LEN_0F7E_P_1): Likewise. (EVEX_LEN_0F7E_P_2): Likewise. (EVEX_LEN_0FD6_P_2): Likewise. * i386-dis.c (USE_EVEX_LEN_TABLE): New. (EVEX_LEN_TABLE): Likewise. (EVEX_LEN_0F6E_P_2): New enum. (EVEX_LEN_0F7E_P_1): Likewise. (EVEX_LEN_0F7E_P_2): Likewise. (EVEX_LEN_0FD6_P_2): Likewise. (evex_len_table): New. (get_valid_dis386): Handle USE_EVEX_LEN_TABLE. * i386-opc.tbl: Set EVex=2 on EVEX.128 only vmovd and vmovq. * i386-tbl.h: Regenerated. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 4ea1d1c694c..3e7680049af 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2018-09-17 H.J. Lu + + PR gas/23670 + * testsuite/gas/i386/evex-lig-2.d: New file. + * testsuite/gas/i386/evex-lig-2.s: Likewise. + * testsuite/gas/i386/x86-64-evex-lig-2.d: Likewise. + * testsuite/gas/i386/x86-64-evex-lig-2.s: Likewise. + * testsuite/gas/i386/i386.exp: Run evex-lig-2 and + x86-64-evex-lig-2. + 2018-09-17 H.J. Lu PR gas/23665 diff --git a/gas/testsuite/gas/i386/evex-lig-2.d b/gas/testsuite/gas/i386/evex-lig-2.d new file mode 100644 index 00000000000..dddcc47b9c4 --- /dev/null +++ b/gas/testsuite/gas/i386/evex-lig-2.d @@ -0,0 +1,18 @@ +#as: -mevexlig=256 +#objdump: -dw +#name: i386 EVEX non-LIG insns with -mevexlig=256 + +.*: +file format .* + + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: 62 f1 7d 08 7e 21 vmovd %xmm4,\(%ecx\) + +[a-f0-9]+: 62 f1 7d 08 7e e1 vmovd %xmm4,%ecx + +[a-f0-9]+: 62 f1 7d 08 6e 21 vmovd \(%ecx\),%xmm4 + +[a-f0-9]+: 62 f1 7d 08 6e e1 vmovd %ecx,%xmm4 + +[a-f0-9]+: 62 f1 fd 08 d6 21 vmovq %xmm4,\(%ecx\) + +[a-f0-9]+: 62 f1 fe 08 7e 21 vmovq \(%ecx\),%xmm4 + +[a-f0-9]+: 62 f1 fe 08 7e f4 vmovq %xmm4,%xmm6 +#pass diff --git a/gas/testsuite/gas/i386/evex-lig-2.s b/gas/testsuite/gas/i386/evex-lig-2.s new file mode 100644 index 00000000000..040f7feede3 --- /dev/null +++ b/gas/testsuite/gas/i386/evex-lig-2.s @@ -0,0 +1,14 @@ +# Check EVEX non-LIG instructions with with -mevexlig=256 + + .allow_index_reg + .text +_start: + {evex} vmovd %xmm4,(%ecx) + {evex} vmovd %xmm4,%ecx + {evex} vmovd (%ecx),%xmm4 + {evex} vmovd %ecx,%xmm4 + + {evex} vmovq %xmm4,(%ecx) + {evex} vmovq (%ecx),%xmm4 + + {evex} vmovq %xmm4,%xmm6 diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index 150a0be1c18..01be072a58f 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -234,6 +234,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]] run_dump_test "evex-lig512" run_dump_test "evex-lig256-intel" run_dump_test "evex-lig512-intel" + run_dump_test "evex-lig-2" run_dump_test "evex-wig1" run_dump_test "evex-wig1-intel" run_dump_test "evex-wig2" @@ -753,6 +754,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t run_dump_test "x86-64-evex-lig512" run_dump_test "x86-64-evex-lig256-intel" run_dump_test "x86-64-evex-lig512-intel" + run_dump_test "x86-64-evex-lig-2" run_dump_test "x86-64-evex-wig1" run_dump_test "x86-64-evex-wig1-intel" run_dump_test "x86-64-evex-wig2" diff --git a/gas/testsuite/gas/i386/x86-64-evex-lig-2.d b/gas/testsuite/gas/i386/x86-64-evex-lig-2.d new file mode 100644 index 00000000000..ebdfe9b0751 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-evex-lig-2.d @@ -0,0 +1,20 @@ +#as: -mevexlig=256 +#objdump: -dw +#name: x86-64 EVEX non-LIG insns with -mevexlig=256 + +.*: +file format .* + + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: 62 f1 7d 08 7e 21 vmovd %xmm4,\(%rcx\) + +[a-f0-9]+: 62 f1 7d 08 7e e1 vmovd %xmm4,%ecx + +[a-f0-9]+: 62 f1 7d 08 6e 21 vmovd \(%rcx\),%xmm4 + +[a-f0-9]+: 62 f1 7d 08 6e e1 vmovd %ecx,%xmm4 + +[a-f0-9]+: 62 f1 fd 08 7e 21 vmovq %xmm4,\(%rcx\) + +[a-f0-9]+: 62 f1 fd 08 7e e1 vmovq %xmm4,%rcx + +[a-f0-9]+: 62 f1 fd 08 6e 21 vmovq \(%rcx\),%xmm4 + +[a-f0-9]+: 62 f1 fd 08 6e e1 vmovq %rcx,%xmm4 + +[a-f0-9]+: 62 f1 fe 08 7e f4 vmovq %xmm4,%xmm6 +#pass diff --git a/gas/testsuite/gas/i386/x86-64-evex-lig-2.s b/gas/testsuite/gas/i386/x86-64-evex-lig-2.s new file mode 100644 index 00000000000..326134936f0 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-evex-lig-2.s @@ -0,0 +1,15 @@ +# Check EVEX non-LIG instructions with with -mevexlig=256 + + .allow_index_reg + .text +_start: + {evex} vmovd %xmm4,(%rcx) + {evex} vmovd %xmm4,%ecx + {evex} vmovd (%rcx),%xmm4 + {evex} vmovd %ecx,%xmm4 + + {evex} vmovq %xmm4,(%rcx) + {evex} vmovq %xmm4,%rcx + {evex} vmovq (%rcx),%xmm4 + {evex} vmovq %rcx,%xmm4 + {evex} vmovq %xmm4,%xmm6 diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 4960430ee7b..5d575070727 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,23 @@ +2018-09-17 H.J. Lu + + PR gas/23670 + * i386-dis-evex.h (evex_table): Use EVEX_LEN_0F6E_P_2, + EVEX_LEN_0F7E_P_1, EVEX_LEN_0F7E_P_2 and EVEX_LEN_0FD6_P_2. + (EVEX_LEN_0F6E_P_2): New EVEX_LEN_TABLE entry. + (EVEX_LEN_0F7E_P_1): Likewise. + (EVEX_LEN_0F7E_P_2): Likewise. + (EVEX_LEN_0FD6_P_2): Likewise. + * i386-dis.c (USE_EVEX_LEN_TABLE): New. + (EVEX_LEN_TABLE): Likewise. + (EVEX_LEN_0F6E_P_2): New enum. + (EVEX_LEN_0F7E_P_1): Likewise. + (EVEX_LEN_0F7E_P_2): Likewise. + (EVEX_LEN_0FD6_P_2): Likewise. + (evex_len_table): New. + (get_valid_dis386): Handle USE_EVEX_LEN_TABLE. + * i386-opc.tbl: Set EVex=2 on EVEX.128 only vmovd and vmovq. + * i386-tbl.h: Regenerated. + 2018-09-17 H.J. Lu PR gas/23665 diff --git a/opcodes/i386-dis-evex.h b/opcodes/i386-dis-evex.h index 932f10a5f14..73b6568d9ab 100644 --- a/opcodes/i386-dis-evex.h +++ b/opcodes/i386-dis-evex.h @@ -1208,7 +1208,7 @@ static const struct dis386 evex_table[][256] = { { { Bad_Opcode }, { Bad_Opcode }, - { VEX_W_TABLE (EVEX_W_0F6E_P_2) }, + { EVEX_LEN_TABLE (EVEX_LEN_0F6E_P_2) }, }, /* PREFIX_EVEX_0F6F */ { @@ -1345,8 +1345,8 @@ static const struct dis386 evex_table[][256] = { /* PREFIX_EVEX_0F7E */ { { Bad_Opcode }, - { VEX_W_TABLE (EVEX_W_0F7E_P_1) }, - { VEX_W_TABLE (EVEX_W_0F7E_P_2) }, + { EVEX_LEN_TABLE (EVEX_LEN_0F7E_P_1) }, + { EVEX_LEN_TABLE (EVEX_LEN_0F7E_P_2) }, }, /* PREFIX_EVEX_0F7F */ { @@ -1414,7 +1414,7 @@ static const struct dis386 evex_table[][256] = { { { Bad_Opcode }, { Bad_Opcode }, - { VEX_W_TABLE (EVEX_W_0FD6_P_2) }, + { EVEX_LEN_TABLE (EVEX_LEN_0FD6_P_2) }, }, /* PREFIX_EVEX_0FD8 */ { @@ -4100,3 +4100,25 @@ static const struct dis386 evex_table[][256] = { }, #endif /* NEED_MOD_TABLE */ +#ifdef NEED_EVEX_LEN_TABLE + /* EVEX_LEN_0F6E_P_2 */ + { + { VEX_W_TABLE (EVEX_W_0F6E_P_2) }, + }, + + /* EVEX_LEN_0F7E_P_1 */ + { + { VEX_W_TABLE (EVEX_W_0F7E_P_1) }, + }, + + /* EVEX_LEN_0F7E_P_2 */ + { + { VEX_W_TABLE (EVEX_W_0F7E_P_2) }, + }, + + /* EVEX_LEN_0FD6_P_2 */ + { + { VEX_W_TABLE (EVEX_W_0FD6_P_2) }, + }, + +#endif /* NEED_EVEX_LEN_TABLE */ diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 89b824c85ca..bc4db68a311 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -703,7 +703,8 @@ enum USE_VEX_C5_TABLE, USE_VEX_LEN_TABLE, USE_VEX_W_TABLE, - USE_EVEX_TABLE + USE_EVEX_TABLE, + USE_EVEX_LEN_TABLE }; #define FLOAT NULL, { { NULL, FLOATCODE } }, 0 @@ -723,6 +724,7 @@ enum #define VEX_LEN_TABLE(I) DIS386 (USE_VEX_LEN_TABLE, (I)) #define VEX_W_TABLE(I) DIS386 (USE_VEX_W_TABLE, (I)) #define EVEX_TABLE(I) DIS386 (USE_EVEX_TABLE, (I)) +#define EVEX_LEN_TABLE(I) DIS386 (USE_EVEX_LEN_TABLE, (I)) enum { @@ -1929,6 +1931,14 @@ enum VEX_LEN_0FXOP_09_81 }; +enum +{ + EVEX_LEN_0F6E_P_2 = 0, + EVEX_LEN_0F7E_P_1, + EVEX_LEN_0F7E_P_2, + EVEX_LEN_0FD6_P_2 +}; + enum { VEX_W_0F41_P_0_LEN_1 = 0, @@ -9882,6 +9892,12 @@ static const struct dis386 vex_len_table[][2] = { }, }; +static const struct dis386 evex_len_table[][3] = { +#define NEED_EVEX_LEN_TABLE +#include "i386-dis-evex.h" +#undef NEED_EVEX_LEN_TABLE +}; + static const struct dis386 vex_w_table[][2] = { { /* VEX_W_0F41_P_0_LEN_1 */ @@ -11542,6 +11558,29 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info) dp = &vex_len_table[dp->op[1].bytemode][vindex]; break; + case USE_EVEX_LEN_TABLE: + if (!vex.evex) + abort (); + + switch (vex.length) + { + case 128: + vindex = 0; + break; + case 256: + vindex = 1; + break; + case 512: + vindex = 2; + break; + default: + abort (); + break; + } + + dp = &evex_len_table[dp->op[1].bytemode][vindex]; + break; + case USE_XOP_8F_TABLE: FETCH_DATA (info, codep + 3); /* All bits in the REX prefix are ignored. */ diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl index 70f78873a10..3aec575b0b1 100644 --- a/opcodes/i386-opc.tbl +++ b/opcodes/i386-opc.tbl @@ -3689,7 +3689,7 @@ vmovaps, 2, 0x28, None, 1, CpuAVX512F, D|Modrm|MaskingMorZ|VexOpcode=0|VexW=1|Di vmovntps, 2, 0x2B, None, 1, CpuAVX512F, Modrm|VexOpcode=0|VexW=1|Disp8ShiftVL|CheckRegSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { RegXMM|RegYMM|RegZMM, XMMword|YMMword|ZMMword|Unspecified|BaseIndex } vmovups, 2, 0x10, None, 1, CpuAVX512F, D|Modrm|MaskingMorZ|VexOpcode=0|VexW=1|Disp8ShiftVL|CheckRegSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { RegXMM|RegYMM|RegZMM|Unspecified|BaseIndex, RegXMM|RegYMM|RegZMM } -vmovd, 2, 0x666E, None, 1, CpuAVX512F, D|Modrm|EVex=4|VexOpcode=0|VexW=1|Disp8MemShift=2|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, RegXMM } +vmovd, 2, 0x666E, None, 1, CpuAVX512F, D|Modrm|EVex=2|VexOpcode=0|VexW=1|Disp8MemShift=2|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, RegXMM } vmovddup, 2, 0xF212, None, 1, CpuAVX512F, Modrm|Masking=3|VexOpcode=0|VexW=2|Disp8ShiftVL|CheckRegSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { RegYMM|RegZMM|Unspecified|BaseIndex, RegYMM|RegZMM } @@ -3712,9 +3712,9 @@ vmovhps, 2, 0x17, None, 1, CpuAVX512F, Modrm|EVex=4|VexOpcode=0|VexW=1|Disp8MemS vmovlps, 3, 0x12, None, 1, CpuAVX512F, Modrm|EVex=4|VexOpcode=0|VexVVVV=1|VexW=1|Disp8MemShift=3|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Qword|Unspecified|BaseIndex, RegXMM, RegXMM } vmovlps, 2, 0x13, None, 1, CpuAVX512F, Modrm|EVex=4|VexOpcode=0|VexW=1|Disp8MemShift=3|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { RegXMM, Qword|Unspecified|BaseIndex } -vmovq, 2, 0x666E, None, 1, CpuAVX512F|Cpu64, D|Modrm|EVex=4|VexOpcode=0|VexW=2|Disp8MemShift=3|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg64|Unspecified|BaseIndex, RegXMM } -vmovq, 2, 0xF37E, None, 1, CpuAVX512F, Load|Modrm|EVex=4|VexOpcode=0|VexW=2|Disp8MemShift=3|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Qword|Unspecified|BaseIndex|RegXMM, RegXMM } -vmovq, 2, 0x66D6, None, 1, CpuAVX512F, Modrm|EVex=4|VexOpcode=0|VexW=2|Disp8MemShift=3|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { RegXMM, Qword|Unspecified|BaseIndex|RegXMM } +vmovq, 2, 0x666E, None, 1, CpuAVX512F|Cpu64, D|Modrm|EVex=2|VexOpcode=0|VexW=2|Disp8MemShift=3|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg64|Unspecified|BaseIndex, RegXMM } +vmovq, 2, 0xF37E, None, 1, CpuAVX512F, Load|Modrm|EVex=2|VexOpcode=0|VexW=2|Disp8MemShift=3|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Qword|Unspecified|BaseIndex|RegXMM, RegXMM } +vmovq, 2, 0x66D6, None, 1, CpuAVX512F, Modrm|EVex=2|VexOpcode=0|VexW=2|Disp8MemShift=3|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { RegXMM, Qword|Unspecified|BaseIndex|RegXMM } vmovsd, 2, 0xF210, None, 1, CpuAVX512F, D|Modrm|EVex=4|MaskingMorZ|VexOpcode=0|VexW=2|Disp8MemShift=3|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Qword|Unspecified|BaseIndex, RegXMM } vmovsd, 3, 0xF210, None, 1, CpuAVX512F, D|Modrm|EVex=4|Masking=3|VexOpcode=0|VexVVVV=1|VexW=2|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { RegXMM|RegMem, RegXMM, RegXMM } diff --git a/opcodes/i386-tbl.h b/opcodes/i386-tbl.h index c4145c690f2..3a0959998fc 100644 --- a/opcodes/i386-tbl.h +++ b/opcodes/i386-tbl.h @@ -35997,7 +35997,7 @@ const insn_template i386_optab[] = 0, 0, 0, 0, 0, 0 } }, { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, { { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, @@ -36730,7 +36730,7 @@ const insn_template i386_optab[] = 0, 0, 0, 1, 0, 0 } }, { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 }, { { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, @@ -36747,7 +36747,7 @@ const insn_template i386_optab[] = 0, 0, 0, 0, 0, 0 } }, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 }, { { { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, @@ -36764,7 +36764,7 @@ const insn_template i386_optab[] = 0, 0, 0, 0, 0, 0 } }, { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 }, { { { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,