This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
[re-sending with the opcodes/i386-opc.tbl changes removed from the mail body, instead adding a compressed attachment of the full patch] The (only) valid broadcast type for an insn can be inferred from other information. gas/ 2018-03-21 Jan Beulich <jbeulich@suse.com> * config/tc-i386.c (struct Broadcast_Operation): Adjust comment. (check_VecOperands): Re-write broadcast validation code. (check_VecOperations): Replace BROADCAST_1TO* uses. * testsuite/gas/i386/inval-avx512f.s: Add various broadcast cases. * testsuite/gas/i386/inval-avx512f.l: Adjust expectations. opcodes/ 2018-03-21 Jan Beulich <jbeulich@suse.com> * i386-opc.h (NO_BROADCAST, BROADCAST_1TO16, BROADCAST_1TO8, BROADCAST_1TO4, BROADCAST_1TO2): Delete. (struct i386_opcode_modifier): Shrink broadcast field to 1 bit. * i386-opc.tbl: Replace Broadcast=<N> by Broadcast. * i386-tlb.h: Re-generate. --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -225,7 +225,7 @@ static struct Mask_Operation mask_op; broadcast factor. */ struct Broadcast_Operation { - /* Type of broadcast: no broadcast, {1to8}, or {1to16}. */ + /* Type of broadcast: {1to2}, {1to4}, {1to8}, or {1to16}. */ int type; /* Index of broadcasted operand. */ @@ -5048,13 +5048,13 @@ check_VecOperands (const insn_template * to the memory operand. */ if (i.broadcast) { - int broadcasted_opnd_size; + i386_operand_type type, overlap; /* Check if specified broadcast is supported in this instruction, and it's applied to memory operand of DWORD or QWORD type, depending on VecESize. */ op = i.broadcast->operand; - if (i.broadcast->type != t->opcode_modifier.broadcast + if (!t->opcode_modifier.broadcast || !i.types[op].bitfield.mem || (t->opcode_modifier.vecesize == 0 && !i.types[op].bitfield.dword @@ -5062,29 +5062,49 @@ check_VecOperands (const insn_template * || (t->opcode_modifier.vecesize == 1 && !i.types[op].bitfield.qword && !i.types[op].bitfield.unspecified)) - goto bad_broadcast; - - broadcasted_opnd_size = t->opcode_modifier.vecesize ? 64 : 32; - if (i.broadcast->type == BROADCAST_1TO16) - broadcasted_opnd_size <<= 4; /* Broadcast 1to16. */ - else if (i.broadcast->type == BROADCAST_1TO8) - broadcasted_opnd_size <<= 3; /* Broadcast 1to8. */ - else if (i.broadcast->type == BROADCAST_1TO4) - broadcasted_opnd_size <<= 2; /* Broadcast 1to4. */ - else if (i.broadcast->type == BROADCAST_1TO2) - broadcasted_opnd_size <<= 1; /* Broadcast 1to2. */ - else - goto bad_broadcast; - - if ((broadcasted_opnd_size == 256 - && !t->operand_types[op].bitfield.ymmword) - || (broadcasted_opnd_size == 512 - && !t->operand_types[op].bitfield.zmmword)) { bad_broadcast: i.error = unsupported_broadcast; return 1; } + + operand_type_set (&type, 0); + switch ((t->opcode_modifier.vecesize ? 8 : 4) * i.broadcast->type) + { + case 8: + type.bitfield.qword = 1; + break; + case 16: + type.bitfield.xmmword = 1; + break; + case 32: + type.bitfield.ymmword = 1; + break; + case 64: + type.bitfield.zmmword = 1; + break; + default: + goto bad_broadcast; + } + + overlap = operand_type_and (type, t->operand_types[op]); + if (operand_type_all_zero (&overlap)) + goto bad_broadcast; + + if (t->opcode_modifier.checkregsize) + { + unsigned int j; + + for (j = 0; j < i.operands; ++j) + { + if (j != op + && !operand_type_register_match(i.types[j], + t->operand_types[j], + type, + t->operand_types[op])) + goto bad_broadcast; + } + } } /* If broadcast is supported in this instruction, we need to check if operand of one-element size isn't specified without broadcast. */ @@ -8441,15 +8461,15 @@ check_VecOperations (char *op_string, ch op_string += 3; if (*op_string == '8') - bcst_type = BROADCAST_1TO8; + bcst_type = 8; else if (*op_string == '4') - bcst_type = BROADCAST_1TO4; + bcst_type = 4; else if (*op_string == '2') - bcst_type = BROADCAST_1TO2; + bcst_type = 2; else if (*op_string == '1' && *(op_string+1) == '6') { - bcst_type = BROADCAST_1TO16; + bcst_type = 16; op_string++; } else --- a/gas/testsuite/gas/i386/inval-avx512f.l +++ b/gas/testsuite/gas/i386/inval-avx512f.l @@ -40,6 +40,66 @@ .*:54: Error: .* .*:57: Error: .* .*:58: Error: .* +.*:61: Error: .*vmovaps.* +.*:62: Error: .*vmovaps.* +.*:63: Error: .*vmovaps.* +.*:64: Error: .*vmovaps.* +.*:66: Error: .*vcvtps2pd.* +.*:67: Error: .*vcvtps2pd.* +.*:69: Error: .*vcvtps2pd.* +.*:71: Error: .*vcvtps2pd.* +.*:73: Error: .*vcvtps2pd.* +.*:74: Error: .*vcvtps2pd.* +.*:77: Error: .*vcvtps2pd.* +.*:78: Error: .*vcvtps2pd.* +.*:79: Error: .*vcvtps2pd.* +.*:81: Error: .*vaddps.* +.*:82: Error: .*vaddps.* +.*:83: Error: .*vaddps.* +.*:86: Error: .*vaddps.* +.*:87: Error: .*vaddps.* +.*:89: Error: .*vaddps.* +.*:91: Error: .*vaddps.* +.*:93: Error: .*vaddps.* +.*:94: Error: .*vaddps.* +.*:96: Error: .*vaddpd.* +.*:97: Error: .*vaddpd.* +.*:99: Error: .*vaddpd.* +.*:101: Error: .*vaddpd.* +.*:103: Error: .*vaddpd.* +.*:104: Error: .*vaddpd.* +.*:107: Error: .*vaddpd.* +.*:108: Error: .*vaddpd.* +.*:109: Error: .*vaddpd.* +.*:112: Error: .*vcvtps2pd.* +.*:113: Error: .*vcvtps2pd.* +.*:117: Error: .*vcvtps2pd.* +.*:118: Error: .*vcvtps2pd.* +.*:119: Error: .*vcvtps2pd.* +.*:121: Error: .*vaddps.* +.*:122: Error: .*vaddps.* +.*:123: Error: .*vaddps.* +.*:125: Error: .*vaddps.* +.*:126: Error: .*vaddps.* +.*:127: Error: .*vaddps.* +.*:130: Error: .*vaddps.* +.*:131: Error: .*vaddps.* +.*:133: Error: .*vaddps.* +.*:135: Error: .*vaddps.* +.*:137: Error: .*vaddps.* +.*:138: Error: .*vaddps.* +.*:140: Error: .*vaddpd.* +.*:141: Error: .*vaddpd.* +.*:142: Error: .*vaddpd.* +.*:144: Error: .*vaddpd.* +.*:145: Error: .*vaddpd.* +.*:147: Error: .*vaddpd.* +.*:149: Error: .*vaddpd.* +.*:151: Error: .*vaddpd.* +.*:152: Error: .*vaddpd.* +.*:155: Error: .*vaddpd.* +.*:156: Error: .*vaddpd.* +.*:157: Error: .*vaddpd.* GAS LISTING .* @@ -103,3 +163,122 @@ GAS LISTING .* GAS LISTING .* #... [ ]*58[ ]+vaddps zmm2\{z\}, zmm1, zmm0 +[ ]*59[ ]* +[ ]*60[ ]+\.att_syntax prefix +[ ]*61[ ]+vmovaps \(%eax\)\{1to2\}, %zmm1 +[ ]*62[ ]+vmovaps \(%eax\)\{1to4\}, %zmm1 +[ ]*63[ ]+vmovaps \(%eax\)\{1to8\}, %zmm1 +[ ]*64[ ]+vmovaps \(%eax\)\{1to16\}, %zmm1 +[ ]*65[ ]* +[ ]*66[ ]+vcvtps2pd \(%eax\)\{1to2\}, %zmm1 +[ ]*67[ ]+vcvtps2pd \(%eax\)\{1to4\}, %zmm1 +[ ]*68 \?\?\?\? 62F17C58[ ]+vcvtps2pd \(%eax\)\{1to8\}, %zmm1 +[ ]*68[ ]+5A08 +[ ]*69[ ]+vcvtps2pd \(%eax\)\{1to16\}, %zmm1 +[ ]*70[ ]* +[ ]*71[ ]+vcvtps2pd \(%eax\)\{1to2\}, %ymm1 +[ ]*72 \?\?\?\? 62F17C38[ ]+vcvtps2pd \(%eax\)\{1to4\}, %ymm1 +[ ]*72[ ]+5A08 +[ ]*73[ ]+vcvtps2pd \(%eax\)\{1to8\}, %ymm1 +[ ]*74[ ]+vcvtps2pd \(%eax\)\{1to16\}, %ymm1 +[ ]*75[ ]* +[ ]*76 \?\?\?\? 62F17C18[ ]+vcvtps2pd \(%eax\)\{1to2\}, %xmm1 +[ ]*76[ ]+5A08 +[ ]*77[ ]+vcvtps2pd \(%eax\)\{1to4\}, %xmm1 +[ ]*78[ ]+vcvtps2pd \(%eax\)\{1to8\}, %xmm1 +[ ]*79[ ]+vcvtps2pd \(%eax\)\{1to16\}, %xmm1 +[ ]*80[ ]+ +[ ]*81[ ]+vaddps \(%eax\)\{1to2\}, %zmm1, %zmm2 +[ ]*82[ ]+vaddps \(%eax\)\{1to4\}, %zmm1, %zmm2 +[ ]*83[ ]+vaddps \(%eax\)\{1to8\}, %zmm1, %zmm2 +[ ]*84 \?\?\?\? 62F17458[ ]+vaddps \(%eax\)\{1to16\}, %zmm1, %zmm2 +[ ]*84[ ]+5810 +[ ]*85[ ]* +[ ]*86[ ]+vaddps \(%eax\)\{1to2\}, %ymm1, %ymm2 +[ ]*87[ ]+vaddps \(%eax\)\{1to4\}, %ymm1, %ymm2 +[ ]*88 \?\?\?\? 62F17438[ ]+vaddps \(%eax\)\{1to8\}, %ymm1, %ymm2 +[ ]*88[ ]+5810 +[ ]*89[ ]+vaddps \(%eax\)\{1to16\}, %ymm1, %ymm2 +[ ]*90[ ]* +[ ]*91[ ]+vaddps \(%eax\)\{1to2\}, %xmm1, %xmm2 +[ ]*92 \?\?\?\? 62F17418[ ]+vaddps \(%eax\)\{1to4\}, %xmm1, %xmm2 +[ ]*92[ ]+5810 +[ ]*93[ ]+vaddps \(%eax\)\{1to8\}, %xmm1, %xmm2 +[ ]*94[ ]+vaddps \(%eax\)\{1to16\}, %xmm1, %xmm2 +[ ]*95[ ]* +[ ]*96[ ]+vaddpd \(%eax\)\{1to2\}, %zmm1, %zmm2 +[ ]*97[ ]+vaddpd \(%eax\)\{1to4\}, %zmm1, %zmm2 +[ ]*98 \?\?\?\? 62F1F558[ ]+vaddpd \(%eax\)\{1to8\}, %zmm1, %zmm2 +[ ]*98[ ]+5810 +[ ]*99[ ]+vaddpd \(%eax\)\{1to16\}, %zmm1, %zmm2 +[ ]*100[ ]* +[ ]*101[ ]+vaddpd \(%eax\)\{1to2\}, %ymm1, %ymm2 +[ ]*102 \?\?\?\? 62F1F538[ ]+vaddpd \(%eax\)\{1to4\}, %ymm1, %ymm2 +[ ]*102[ ]+5810 +[ ]*103[ ]+vaddpd \(%eax\)\{1to8\}, %ymm1, %ymm2 +[ ]*104[ ]+vaddpd \(%eax\)\{1to16\}, %ymm1, %ymm2 +[ ]*105[ ]* +[ ]*106 \?\?\?\? 62F1F518[ ]+vaddpd \(%eax\)\{1to2\}, %xmm1, %xmm2 +GAS LISTING .* +#... +[ ]*106[ ]+5810 +[ ]*107[ ]+vaddpd \(%eax\)\{1to4\}, %xmm1, %xmm2 +[ ]*108[ ]+vaddpd \(%eax\)\{1to8\}, %xmm1, %xmm2 +[ ]*109[ ]+vaddpd \(%eax\)\{1to16\}, %xmm1, %xmm2 +[ ]*110[ ]* +[ ]*111[ ]+\.intel_syntax noprefix +[ ]*112[ ]+vcvtps2pd zmm1, QWORD PTR \[eax\] +[ ]*113[ ]+vcvtps2pd ymm1, QWORD PTR \[eax\] +[ ]*114 \?\?\?\? C5F85A08[ ]+vcvtps2pd xmm1, QWORD PTR \[eax\] +[ ]*115[ ]* +[ ]*116 \?\?\?\? 62F17C18[ ]+vcvtps2pd xmm1, DWORD PTR \[eax\]\{1to2\} +[ ]*116[ ]+5A08 +[ ]*117[ ]+vcvtps2pd xmm1, DWORD PTR \[eax\]\{1to4\} +[ ]*118[ ]+vcvtps2pd xmm1, DWORD PTR \[eax\]\{1to8\} +[ ]*119[ ]+vcvtps2pd xmm1, DWORD PTR \[eax\]\{1to16\} +[ ]*120[ ]* +[ ]*121[ ]+vaddps zmm2, zmm1, QWORD PTR \[eax\] +[ ]*122[ ]+vaddps ymm2, ymm1, QWORD PTR \[eax\] +[ ]*123[ ]+vaddps xmm2, xmm1, QWORD PTR \[eax\] +[ ]*124[ ]* +[ ]*125[ ]+vaddps zmm2, zmm1, DWORD PTR \[eax\]\{1to2\} +[ ]*126[ ]+vaddps zmm2, zmm1, DWORD PTR \[eax\]\{1to4\} +[ ]*127[ ]+vaddps zmm2, zmm1, DWORD PTR \[eax\]\{1to8\} +[ ]*128 \?\?\?\? 62F17458[ ]+vaddps zmm2, zmm1, DWORD PTR \[eax\]\{1to16\} +[ ]*128[ ]+5810 +[ ]*129[ ]* +[ ]*130[ ]+vaddps ymm2, ymm1, DWORD PTR \[eax\]\{1to2\} +[ ]*131[ ]+vaddps ymm2, ymm1, DWORD PTR \[eax\]\{1to4\} +[ ]*132 \?\?\?\? 62F17438[ ]+vaddps ymm2, ymm1, DWORD PTR \[eax\]\{1to8\} +[ ]*132[ ]+5810 +[ ]*133[ ]+vaddps ymm2, ymm1, DWORD PTR \[eax\]\{1to16\} +[ ]*134[ ]* +[ ]*135[ ]+vaddps xmm2, xmm1, DWORD PTR \[eax\]\{1to2\} +[ ]*136 \?\?\?\? 62F17418[ ]+vaddps xmm2, xmm1, DWORD PTR \[eax\]\{1to4\} +[ ]*136[ ]+5810 +[ ]*137[ ]+vaddps xmm2, xmm1, DWORD PTR \[eax\]\{1to8\} +[ ]*138[ ]+vaddps xmm2, xmm1, DWORD PTR \[eax\]\{1to16\} +[ ]*139[ ]* +[ ]*140[ ]+vaddpd zmm2, zmm1, DWORD PTR \[eax\] +[ ]*141[ ]+vaddpd ymm2, ymm1, DWORD PTR \[eax\] +[ ]*142[ ]+vaddpd xmm2, xmm1, DWORD PTR \[eax\] +[ ]*143[ ]* +[ ]*144[ ]+vaddpd zmm2, zmm1, QWORD PTR \[eax\]\{1to2\} +[ ]*145[ ]+vaddpd zmm2, zmm1, QWORD PTR \[eax\]\{1to4\} +[ ]*146 \?\?\?\? 62F1F558[ ]+vaddpd zmm2, zmm1, QWORD PTR \[eax\]\{1to8\} +[ ]*146[ ]+5810 +[ ]*147[ ]+vaddpd zmm2, zmm1, QWORD PTR \[eax\]\{1to16\} +[ ]*148[ ]* +[ ]*149[ ]+vaddpd ymm2, ymm1, QWORD PTR \[eax\]\{1to2\} +[ ]*150 \?\?\?\? 62F1F538[ ]+vaddpd ymm2, ymm1, QWORD PTR \[eax\]\{1to4\} +[ ]*150[ ]+5810 +[ ]*151[ ]+vaddpd ymm2, ymm1, QWORD PTR \[eax\]\{1to8\} +[ ]*152[ ]+vaddpd ymm2, ymm1, QWORD PTR \[eax\]\{1to16\} +[ ]*153[ ]* +[ ]*154 \?\?\?\? 62F1F518[ ]+vaddpd xmm2, xmm1, QWORD PTR \[eax\]\{1to2\} +[ ]*154[ ]+5810 +[ ]*155[ ]+vaddpd xmm2, xmm1, QWORD PTR \[eax\]\{1to4\} +GAS LISTING .* +#... +[ ]*156[ ]+vaddpd xmm2, xmm1, QWORD PTR \[eax\]\{1to8\} +[ ]*157[ ]+vaddpd xmm2, xmm1, QWORD PTR \[eax\]\{1to16\} --- a/gas/testsuite/gas/i386/inval-avx512f.s +++ b/gas/testsuite/gas/i386/inval-avx512f.s @@ -56,3 +56,102 @@ _start: .intel_syntax noprefix vaddps zmm2{ecx}, zmm1, zmm0 vaddps zmm2{z}, zmm1, zmm0 + + .att_syntax prefix + vmovaps (%eax){1to2}, %zmm1 + vmovaps (%eax){1to4}, %zmm1 + vmovaps (%eax){1to8}, %zmm1 + vmovaps (%eax){1to16}, %zmm1 + + vcvtps2pd (%eax){1to2}, %zmm1 + vcvtps2pd (%eax){1to4}, %zmm1 + vcvtps2pd (%eax){1to8}, %zmm1 + vcvtps2pd (%eax){1to16}, %zmm1 + + vcvtps2pd (%eax){1to2}, %ymm1 + vcvtps2pd (%eax){1to4}, %ymm1 + vcvtps2pd (%eax){1to8}, %ymm1 + vcvtps2pd (%eax){1to16}, %ymm1 + + vcvtps2pd (%eax){1to2}, %xmm1 + vcvtps2pd (%eax){1to4}, %xmm1 + vcvtps2pd (%eax){1to8}, %xmm1 + vcvtps2pd (%eax){1to16}, %xmm1 + + vaddps (%eax){1to2}, %zmm1, %zmm2 + vaddps (%eax){1to4}, %zmm1, %zmm2 + vaddps (%eax){1to8}, %zmm1, %zmm2 + vaddps (%eax){1to16}, %zmm1, %zmm2 + + vaddps (%eax){1to2}, %ymm1, %ymm2 + vaddps (%eax){1to4}, %ymm1, %ymm2 + vaddps (%eax){1to8}, %ymm1, %ymm2 + vaddps (%eax){1to16}, %ymm1, %ymm2 + + vaddps (%eax){1to2}, %xmm1, %xmm2 + vaddps (%eax){1to4}, %xmm1, %xmm2 + vaddps (%eax){1to8}, %xmm1, %xmm2 + vaddps (%eax){1to16}, %xmm1, %xmm2 + + vaddpd (%eax){1to2}, %zmm1, %zmm2 + vaddpd (%eax){1to4}, %zmm1, %zmm2 + vaddpd (%eax){1to8}, %zmm1, %zmm2 + vaddpd (%eax){1to16}, %zmm1, %zmm2 + + vaddpd (%eax){1to2}, %ymm1, %ymm2 + vaddpd (%eax){1to4}, %ymm1, %ymm2 + vaddpd (%eax){1to8}, %ymm1, %ymm2 + vaddpd (%eax){1to16}, %ymm1, %ymm2 + + vaddpd (%eax){1to2}, %xmm1, %xmm2 + vaddpd (%eax){1to4}, %xmm1, %xmm2 + vaddpd (%eax){1to8}, %xmm1, %xmm2 + vaddpd (%eax){1to16}, %xmm1, %xmm2 + + .intel_syntax noprefix + vcvtps2pd zmm1, QWORD PTR [eax] + vcvtps2pd ymm1, QWORD PTR [eax] + vcvtps2pd xmm1, QWORD PTR [eax] + + vcvtps2pd xmm1, DWORD PTR [eax]{1to2} + vcvtps2pd xmm1, DWORD PTR [eax]{1to4} + vcvtps2pd xmm1, DWORD PTR [eax]{1to8} + vcvtps2pd xmm1, DWORD PTR [eax]{1to16} + + vaddps zmm2, zmm1, QWORD PTR [eax] + vaddps ymm2, ymm1, QWORD PTR [eax] + vaddps xmm2, xmm1, QWORD PTR [eax] + + vaddps zmm2, zmm1, DWORD PTR [eax]{1to2} + vaddps zmm2, zmm1, DWORD PTR [eax]{1to4} + vaddps zmm2, zmm1, DWORD PTR [eax]{1to8} + vaddps zmm2, zmm1, DWORD PTR [eax]{1to16} + + vaddps ymm2, ymm1, DWORD PTR [eax]{1to2} + vaddps ymm2, ymm1, DWORD PTR [eax]{1to4} + vaddps ymm2, ymm1, DWORD PTR [eax]{1to8} + vaddps ymm2, ymm1, DWORD PTR [eax]{1to16} + + vaddps xmm2, xmm1, DWORD PTR [eax]{1to2} + vaddps xmm2, xmm1, DWORD PTR [eax]{1to4} + vaddps xmm2, xmm1, DWORD PTR [eax]{1to8} + vaddps xmm2, xmm1, DWORD PTR [eax]{1to16} + + vaddpd zmm2, zmm1, DWORD PTR [eax] + vaddpd ymm2, ymm1, DWORD PTR [eax] + vaddpd xmm2, xmm1, DWORD PTR [eax] + + vaddpd zmm2, zmm1, QWORD PTR [eax]{1to2} + vaddpd zmm2, zmm1, QWORD PTR [eax]{1to4} + vaddpd zmm2, zmm1, QWORD PTR [eax]{1to8} + vaddpd zmm2, zmm1, QWORD PTR [eax]{1to16} + + vaddpd ymm2, ymm1, QWORD PTR [eax]{1to2} + vaddpd ymm2, ymm1, QWORD PTR [eax]{1to4} + vaddpd ymm2, ymm1, QWORD PTR [eax]{1to8} + vaddpd ymm2, ymm1, QWORD PTR [eax]{1to16} + + vaddpd xmm2, xmm1, QWORD PTR [eax]{1to2} + vaddpd xmm2, xmm1, QWORD PTR [eax]{1to4} + vaddpd xmm2, xmm1, QWORD PTR [eax]{1to8} + vaddpd xmm2, xmm1, QWORD PTR [eax]{1to16} --- a/opcodes/i386-opc.h +++ b/opcodes/i386-opc.h @@ -572,16 +572,6 @@ enum */ VecESize, - /* Broadcast factor. - 0: No broadcast. - 1: 1to16 broadcast. - 2: 1to8 broadcast. - */ -#define NO_BROADCAST 0 -#define BROADCAST_1TO16 1 -#define BROADCAST_1TO8 2 -#define BROADCAST_1TO4 3 -#define BROADCAST_1TO2 4 Broadcast, /* Static rounding control is supported. */ @@ -672,7 +662,7 @@ typedef struct i386_opcode_modifier unsigned int evex:3; unsigned int masking:2; unsigned int vecesize:1; - unsigned int broadcast:3; + unsigned int broadcast:1; unsigned int staticrounding:1; unsigned int sae:1; unsigned int disp8memshift:3;
Attachment:
binutils-master-x86-broadcast-boolean.patch.gz
Description: GNU Zip compressed data
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |