]> granicus.if.org Git - yasm/commitdiff
Fix handling of CPU flags; the old code would simply take the last CPU
authorPeter Johnson <peter@tortall.net>
Wed, 18 Oct 2006 04:21:21 +0000 (04:21 -0000)
committerPeter Johnson <peter@tortall.net>
Wed, 18 Oct 2006 04:21:21 +0000 (04:21 -0000)
setting in the file and use it against the entire file (oops).
(first half of #83)

Also make the error message a lot nicer, at least for ones we detect early
(shl ax, 2 in 8086 mode still gives the old message).

While I'm here, upgrade movsd to CPU_386.

svn path=/trunk/yasm/; revision=1654

modules/arch/x86/tests/cpubasic-err.asm
modules/arch/x86/tests/cpubasic-err.errwarn
modules/arch/x86/x86id.c
modules/arch/x86/x86parse.gap

index d381eeb6e94b993b0f8985ba0ae2735d1ee9470f..a1f71cd1d12e598e0be048673fc9f43c412be830 100644 (file)
@@ -1,2 +1,17 @@
 [cpu 8086]
 pause
+
+shl ax, 2
+
+cpu 386
+fninit
+
+cpu 386 fpu
+fninit
+
+cpu 8086
+
+shl ax, 1
+shl ax, 2
+movsd
+
index c278d28dcaf762775ee260575c0eaaa9c2be10d9..4f1be6f23fa2e360195619712b7f9559ab23d3c6 100644 (file)
@@ -1 +1,5 @@
--:2: invalid combination of opcode and operands
+-:2: warning: `pause' is an instruction in CPU P4
+-:4: invalid combination of opcode and operands
+-:7: warning: `fninit' is an instruction in CPU FPU
+-:15: invalid combination of opcode and operands
+-:16: warning: `movsd' is an instruction in CPU 386
index d406c93711e78816e0eb76afea50c4f8122ab0f7..e44a7a5972f2856e897b196fdceb92418da42654 100644 (file)
@@ -2221,7 +2221,7 @@ x86_finalize_jmp(yasm_arch *arch, yasm_bytecode *bc, yasm_bytecode *prev_bc,
     jmp->nearop.len = 0;
     for (; num_info>0 && (jmp->shortop.len == 0 || jmp->nearop.len == 0);
         num_info--, info++) {
-       unsigned long cpu = info->cpu | data[2];
+       unsigned long cpu = info->cpu;
 
        if ((cpu & CPU_64) && mode_bits != 64)
            continue;
@@ -2229,7 +2229,7 @@ x86_finalize_jmp(yasm_arch *arch, yasm_bytecode *bc, yasm_bytecode *prev_bc,
            continue;
        cpu &= ~(CPU_64 | CPU_Not64);
 
-       if ((arch_x86->cpu_enabled & cpu) != cpu)
+       if ((data[2] & cpu) != cpu)
            continue;
 
        if (info->num_operands == 0)
@@ -2369,7 +2369,7 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
        int mismatch = 0;
 
        /* Match CPU */
-       cpu = info->cpu | data[2];
+       cpu = info->cpu;
 
        if ((cpu & CPU_64) && mode_bits != 64)
            continue;
@@ -2377,7 +2377,7 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
            continue;
        cpu &= ~(CPU_64 | CPU_Not64);
 
-       if ((arch_x86->cpu_enabled & cpu) != cpu)
+       if ((data[2] & cpu) != cpu)
            continue;
 
        /* Match # of operands */
@@ -3060,6 +3060,76 @@ typedef struct regtmod_parse_data {
 /* Pull in all parse data */
 #include "x86parse.c"
 
+static const char *
+cpu_find_reverse(unsigned long cpu)
+{
+    static char cpuname[200];
+
+    cpuname[0] = '\0';
+
+    if (cpu & CPU_Prot)
+       strcat(cpuname, " Protected");
+    if (cpu & CPU_Undoc)
+       strcat(cpuname, " Undocumented");
+    if (cpu & CPU_Obs)
+       strcat(cpuname, " Obsolete");
+    if (cpu & CPU_Priv)
+       strcat(cpuname, " Privileged");
+
+    if (cpu & CPU_FPU)
+       strcat(cpuname, " FPU");
+    if (cpu & CPU_MMX)
+       strcat(cpuname, " MMX");
+    if (cpu & CPU_SSE)
+       strcat(cpuname, " SSE");
+    if (cpu & CPU_SSE2)
+       strcat(cpuname, " SSE2");
+    if (cpu & CPU_SSE3)
+       strcat(cpuname, " SSE3");
+    if (cpu & CPU_3DNow)
+       strcat(cpuname, " 3DNow");
+    if (cpu & CPU_Cyrix)
+       strcat(cpuname, " Cyrix");
+    if (cpu & CPU_AMD)
+       strcat(cpuname, " AMD");
+    if (cpu & CPU_SMM)
+       strcat(cpuname, " SMM");
+    if (cpu & CPU_SVM)
+       strcat(cpuname, " SVM");
+    if (cpu & CPU_PadLock)
+       strcat(cpuname, " PadLock");
+    if (cpu & CPU_EM64T)
+       strcat(cpuname, " EM64T");
+    if (cpu & CPU_SSE4)
+       strcat(cpuname, " SSSE3");
+
+    if (cpu & CPU_186)
+       strcat(cpuname, " 186");
+    if (cpu & CPU_286)
+       strcat(cpuname, " 286");
+    if (cpu & CPU_386)
+       strcat(cpuname, " 386");
+    if (cpu & CPU_486)
+       strcat(cpuname, " 486");
+    if (cpu & CPU_586)
+       strcat(cpuname, " 586");
+    if (cpu & CPU_686)
+       strcat(cpuname, " 686");
+    if (cpu & CPU_P3)
+       strcat(cpuname, " P3");
+    if (cpu & CPU_P4)
+       strcat(cpuname, " P4");
+    if (cpu & CPU_IA64)
+       strcat(cpuname, " IA64");
+    if (cpu & CPU_K6)
+       strcat(cpuname, " K6");
+    if (cpu & CPU_Athlon)
+       strcat(cpuname, " Athlon");
+    if (cpu & CPU_Hammer)
+       strcat(cpuname, " Hammer");
+    return cpuname;
+}
+
 yasm_arch_insnprefix
 yasm_x86__parse_check_insnprefix(yasm_arch *arch, unsigned long data[4],
                                 const char *id, size_t id_len)
@@ -3106,9 +3176,17 @@ yasm_x86__parse_check_insnprefix(yasm_arch *arch, unsigned long data[4],
            return YASM_ARCH_INSN;
        }
 
+       cpu &= ~(CPU_64 | CPU_Not64);
+       if ((arch_x86->cpu_enabled & cpu) != cpu) {
+           yasm_warn_set(YASM_WARN_GENERAL,
+                         N_("`%s' is an instruction in CPU%s"), id,
+                         cpu_find_reverse(cpu));
+           return YASM_ARCH_NOTINSNPREFIX;
+       }
+
        data[0] = (unsigned long)pdata->group;
        data[1] = pdata->data1;
-       data[2] = cpu;
+       data[2] = arch_x86->cpu_enabled;
        data[3] = (((unsigned long)pdata->flags)<<8) | arch_x86->mode_bits;
        return YASM_ARCH_INSN;
     } else {
index 4741ec694b5629e6959c794dce304ef028b4b75f..6060bf1091d22b35ea9fa4ee13c60511faa41805 100644 (file)
@@ -252,7 +252,7 @@ INSN        gas     lodsl   NONE    onebyte 0x20AD          CPU_386
 INSN   -       lodsq   NONE    onebyte 0x40AD          CPU_Hammer|CPU_64
 INSN   -       movsb   NONE    onebyte 0x00A4          CPU_Any
 INSN   -       movsw   NONE    onebyte 0x10A5          CPU_Any
-INSN   -       movsd   NONE    movsd   0               CPU_Any
+INSN   -       movsd   NONE    movsd   0               CPU_386
 INSN   gas     movsl   NONE    onebyte 0x20A5          CPU_386
 INSN   -       movsq   NONE    onebyte 0x40A5          CPU_Hammer|CPU_64
 # smov alias for movs in GAS mode
@@ -924,9 +924,13 @@ CPU_FEATURE        cyrix   CPU_Cyrix
 CPU_FEATURE    amd     CPU_AMD
 CPU_FEATURE    smm     CPU_SMM
 CPU_FEATURE    prot    CPU_Prot
+CPU_FEATURE    protected       CPU_Prot
 CPU_FEATURE    undoc   CPU_Undoc
+CPU_FEATURE    undocumented    CPU_Undoc
 CPU_FEATURE    obs     CPU_Obs
+CPU_FEATURE    obsolete        CPU_Obs
 CPU_FEATURE    priv    CPU_Priv
+CPU_FEATURE    privileged      CPU_Priv
 CPU_FEATURE    svm     CPU_SVM
 CPU_FEATURE    padlock CPU_PadLock
 CPU_FEATURE    em64t   CPU_EM64T