From f48ff2ae3d74966f635449f9a69e374ed8da3da2 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Wed, 13 Dec 2006 18:00:00 +0000 Subject: [PATCH] gas/ 2006-12-13 H.J. Lu PR gas/3712 * config/tc-i386.c (match_template): Use MAX_OPERANDS for the number of operands. Issue an error if MAX_OPERANDS != 4. Add the 4th operand check. gas/testsuite/ 2006-12-13 H.J. Lu PR gas/3712 * gas/i386/inval.s: Add invalid insertq. * gas/i386/x86-64-inval.s: Likewise. * gas/i386/inval.l: Updated. * gas/i386/x86-64-inval.l: Likewise. --- gas/ChangeLog | 7 +++ gas/config/tc-i386.c | 61 +++++++++++++++++++-------- gas/testsuite/ChangeLog | 9 ++++ gas/testsuite/gas/i386/inval.l | 2 + gas/testsuite/gas/i386/inval.s | 1 + gas/testsuite/gas/i386/x86-64-inval.l | 2 + gas/testsuite/gas/i386/x86-64-inval.s | 1 + 7 files changed, 66 insertions(+), 17 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 7ef8904d516..94357ae4dfa 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2006-12-13 H.J. Lu + + PR gas/3712 + * config/tc-i386.c (match_template): Use MAX_OPERANDS for the + number of operands. Issue an error if MAX_OPERANDS != 4. Add + the 4th operand check. + 2006-12-13 Paul Brook * config/tc-arm.c (arm_arch_option_table): Add v7-{a,r,m}. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 767e7e3bd05..01f56b09688 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -2568,12 +2568,16 @@ match_template () { /* Points to template once we've found it. */ const template *t; - unsigned int overlap0, overlap1, overlap2; + unsigned int overlap0, overlap1, overlap2, overlap3; unsigned int found_reverse_match; int suffix_check; - unsigned int operand_types [3]; + unsigned int operand_types [MAX_OPERANDS]; int addr_prefix_disp; +#if MAX_OPERANDS != 4 +# error "MAX_OPERANDS must be 4." +#endif + #define MATCH(overlap, given, template) \ ((overlap & ~JumpAbsolute) \ && (((given) & (BaseIndex | JumpAbsolute)) \ @@ -2590,10 +2594,12 @@ match_template () overlap0 = 0; overlap1 = 0; overlap2 = 0; + overlap3 = 0; found_reverse_match = 0; operand_types [0] = 0; operand_types [1] = 0; operand_types [2] = 0; + operand_types [3] = 0; addr_prefix_disp = -1; suffix_check = (i.suffix == BYTE_MNEM_SUFFIX ? No_bSuf @@ -2625,6 +2631,7 @@ match_template () operand_types [0] = t->operand_types [0]; operand_types [1] = t->operand_types [1]; operand_types [2] = t->operand_types [2]; + operand_types [3] = t->operand_types [3]; /* In general, don't allow 64-bit operands in 32-bit mode. */ if (i.suffix == QWORD_MNEM_SUFFIX @@ -2670,7 +2677,7 @@ match_template () break; } - for (j = 0; j < 3; j++) + for (j = 0; j < MAX_OPERANDS; j++) { /* There should be only one Disp operand. */ if ((operand_types[j] & DispOff)) @@ -2692,6 +2699,7 @@ match_template () break; case 2: case 3: + case 4: overlap1 = i.types[1] & operand_types[1]; if (!MATCH (overlap0, i.types[0], operand_types[0]) || !MATCH (overlap1, i.types[1], operand_types[1]) @@ -2726,23 +2734,42 @@ match_template () we've found. */ found_reverse_match = t->opcode_modifier & (D | FloatDR); } - /* Found a forward 2 operand match here. */ - else if (t->operands == 3) + else { - /* Here we make use of the fact that there are no - reverse match 3 operand instructions, and all 3 - operand instructions only need to be checked for - register consistency between operands 2 and 3. */ - overlap2 = i.types[2] & operand_types[2]; - if (!MATCH (overlap2, i.types[2], operand_types[2]) - || !CONSISTENT_REGISTER_MATCH (overlap1, i.types[1], - operand_types[1], - overlap2, i.types[2], - operand_types[2])) + /* Found a forward 2 operand match here. */ + if (t->operands > 2) + overlap2 = i.types[2] & operand_types[2]; + if (t->operands > 3) + overlap3 = i.types[3] & operand_types[3]; - continue; + switch (t->operands) + { + case 4: + if (!MATCH (overlap3, i.types[3], operand_types[3]) + || !CONSISTENT_REGISTER_MATCH (overlap2, + i.types[2], + operand_types[2], + overlap3, + i.types[3], + operand_types[3])) + continue; + case 3: + /* Here we make use of the fact that there are no + reverse match 3 operand instructions, and all 3 + operand instructions only need to be checked for + register consistency between operands 2 and 3. */ + if (!MATCH (overlap2, i.types[2], operand_types[2]) + || !CONSISTENT_REGISTER_MATCH (overlap1, + i.types[1], + operand_types[1], + overlap2, + i.types[2], + operand_types[2])) + continue; + break; + } } - /* Found either forward/reverse 2 or 3 operand match here: + /* Found either forward/reverse 2, 3 or 4 operand match here: slip through to break. */ } if (t->cpu_flags & ~cpu_arch_flags) diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index fb37d77b45e..4e8b4ff9002 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2006-12-13 H.J. Lu + + PR gas/3712 + * gas/i386/inval.s: Add invalid insertq. + * gas/i386/x86-64-inval.s: Likewise. + + * gas/i386/inval.l: Updated. + * gas/i386/x86-64-inval.l: Likewise. + 2006-12-08 Christian Groessler * gas/z8k/reglabel.d: New test. diff --git a/gas/testsuite/gas/i386/inval.l b/gas/testsuite/gas/i386/inval.l index 9f32368b7e4..8abcbde95a7 100644 --- a/gas/testsuite/gas/i386/inval.l +++ b/gas/testsuite/gas/i386/inval.l @@ -46,6 +46,7 @@ .*:47: Error: .* .*:48: Error: .* .*:49: Error: .* +.*:50: Error: .* GAS LISTING .* @@ -98,3 +99,4 @@ GAS LISTING .* 47 [ ]* fcompll 28\(%ebp\) 48 [ ]* fldlw \(%eax\) 49 [ ]* movl \$%ebx,%eax + 50 [ ]* insertq \$4,\$2,%xmm2,%ebx diff --git a/gas/testsuite/gas/i386/inval.s b/gas/testsuite/gas/i386/inval.s index 1571a2f4fa7..5b440ed0b55 100644 --- a/gas/testsuite/gas/i386/inval.s +++ b/gas/testsuite/gas/i386/inval.s @@ -47,3 +47,4 @@ foo: jaw foo fcompll 28(%ebp) fldlw (%eax) movl $%ebx,%eax + insertq $4,$2,%xmm2,%ebx diff --git a/gas/testsuite/gas/i386/x86-64-inval.l b/gas/testsuite/gas/i386/x86-64-inval.l index aa080cba46a..2e45b4674c8 100644 --- a/gas/testsuite/gas/i386/x86-64-inval.l +++ b/gas/testsuite/gas/i386/x86-64-inval.l @@ -48,6 +48,7 @@ .*:49: Error: .* .*:50: Error: .* .*:51: Error: .* +.*:52: Error: .* GAS LISTING .* @@ -102,3 +103,4 @@ GAS LISTING .* 49 [ ]*pushfl # can't have 32-bit stack operands 50 [ ]*popfl # can't have 32-bit stack operands 51 [ ]*retl # can't have 32-bit stack operands + 52 [ ]*insertq \$4,\$2,%xmm2,%ebx # The last operand must be XMM register. diff --git a/gas/testsuite/gas/i386/x86-64-inval.s b/gas/testsuite/gas/i386/x86-64-inval.s index b069a282e5c..68f4cb5ed01 100644 --- a/gas/testsuite/gas/i386/x86-64-inval.s +++ b/gas/testsuite/gas/i386/x86-64-inval.s @@ -49,3 +49,4 @@ foo: jcxz foo # No prefix exists to select CX as a counter pushfl # can't have 32-bit stack operands popfl # can't have 32-bit stack operands retl # can't have 32-bit stack operands + insertq $4,$2,%xmm2,%ebx # The last operand must be XMM register. -- 2.30.2