Skip to content

Commit 4709cfe

Browse files
author
H. Peter Anvin (Intel)
committed
Show instruction mismatch errors if another error terminates assembly
Instruction mismatch errors have been held until the last assembly pass in case changed %if statements cause a code path to be elided in subsequent passes. However, it is confusing to the user if error messages aren't shown if another error terminates assembly. Use the already existing mechanism for warnings to hold the messages unless another error terminates assembly. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
1 parent ca67f50 commit 4709cfe

File tree

4 files changed

+88
-72
lines changed

4 files changed

+88
-72
lines changed

asm/assemble.c

Lines changed: 80 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,82 @@ static void out_reladdr(struct out_data *data, const struct operand *opx,
634634
out(data);
635635
}
636636

637+
/* Issue an error message on match failure */
638+
static void no_match_error(enum match_result m, const insn *ins)
639+
{
640+
/* No match */
641+
switch (m) {
642+
case MERR_INVALOP:
643+
nasm_holderr("invalid combination of opcode and operands");
644+
break;
645+
case MERR_OPSIZEINVAL:
646+
nasm_holderr("invalid operand sizes for instruction");
647+
break;
648+
case MERR_OPSIZEMISSING:
649+
nasm_holderr("operation size not specified");
650+
break;
651+
case MERR_OPSIZEMISMATCH:
652+
nasm_holderr("mismatch in operand sizes");
653+
break;
654+
case MERR_BRNOTHERE:
655+
nasm_holderr("broadcast not permitted on this operand");
656+
break;
657+
case MERR_BRNUMMISMATCH:
658+
nasm_holderr("mismatch in the number of broadcasting elements");
659+
break;
660+
case MERR_MASKNOTHERE:
661+
nasm_holderr("mask not permitted on this operand");
662+
break;
663+
case MERR_DECONOTHERE:
664+
nasm_holderr("unsupported mode decorator for instruction");
665+
break;
666+
case MERR_BADCPU:
667+
nasm_holderr("no instruction for this cpu level");
668+
break;
669+
case MERR_BADMODE:
670+
nasm_holderr("instruction not supported in %d-bit mode", ins->bits);
671+
break;
672+
case MERR_ENCMISMATCH:
673+
if (!ins->prefixes[PPS_REX]) {
674+
nasm_holderr("instruction not encodable without explicit prefix");
675+
} else {
676+
nasm_holderr("instruction not encodable with %s prefix",
677+
prefix_name(ins->prefixes[PPS_REX]));
678+
}
679+
break;
680+
case MERR_BADBND:
681+
case MERR_BADREPNE:
682+
nasm_holderr("%s prefix is not allowed",
683+
prefix_name(ins->prefixes[PPS_REP]));
684+
break;
685+
case MERR_REGSETSIZE:
686+
nasm_holderr("invalid register set size");
687+
break;
688+
case MERR_REGSET:
689+
nasm_holderr("register set not valid for operand");
690+
break;
691+
case MERR_WRONGIMM:
692+
nasm_holderr("operand/operator invalid for this instruction");
693+
break;
694+
case MERR_BADZU:
695+
nasm_holderr("{zu} not applicable to this instruction");
696+
break;
697+
case MERR_MEMZU:
698+
nasm_holderr("{zu} invalid for non-register destination");
699+
break;
700+
case MERR_BADNF:
701+
nasm_holderr("{nf} not available for this instruction");
702+
break;
703+
case MERR_REQNF:
704+
nasm_holderr("{nf} required for this instruction");
705+
break;
706+
default:
707+
if (m < MOK_GOOD)
708+
nasm_holderr("invalid use of instruction");
709+
break;
710+
}
711+
}
712+
637713
/* This is a real hack. The jcc8 or jmp8 byte code must come first. */
638714
static enum match_result jmp_match(const struct itemplate *temp, const insn *ins)
639715
{
@@ -816,7 +892,6 @@ static int64_t assemble(insn *instruction)
816892
const struct itemplate *temp;
817893
enum match_result m;
818894
const int64_t start = instruction->loc.offset;
819-
const int bits = instruction->bits;
820895

821896
if (instruction->opcode == I_none)
822897
return 0;
@@ -999,75 +1074,7 @@ static int64_t assemble(insn *instruction)
9991074

10001075
nasm_assert(data.loc.offset - start == data.inslen);
10011076
} else {
1002-
/* No match */
1003-
switch (m) {
1004-
case MERR_INVALOP:
1005-
default:
1006-
nasm_nonfatal("invalid combination of opcode and operands");
1007-
break;
1008-
case MERR_OPSIZEINVAL:
1009-
nasm_nonfatal("invalid operand sizes for instruction");
1010-
break;
1011-
case MERR_OPSIZEMISSING:
1012-
nasm_nonfatal("operation size not specified");
1013-
break;
1014-
case MERR_OPSIZEMISMATCH:
1015-
nasm_nonfatal("mismatch in operand sizes");
1016-
break;
1017-
case MERR_BRNOTHERE:
1018-
nasm_nonfatal("broadcast not permitted on this operand");
1019-
break;
1020-
case MERR_BRNUMMISMATCH:
1021-
nasm_nonfatal("mismatch in the number of broadcasting elements");
1022-
break;
1023-
case MERR_MASKNOTHERE:
1024-
nasm_nonfatal("mask not permitted on this operand");
1025-
break;
1026-
case MERR_DECONOTHERE:
1027-
nasm_nonfatal("unsupported mode decorator for instruction");
1028-
break;
1029-
case MERR_BADCPU:
1030-
nasm_nonfatal("no instruction for this cpu level");
1031-
break;
1032-
case MERR_BADMODE:
1033-
nasm_nonfatal("instruction not supported in %d-bit mode", bits);
1034-
break;
1035-
case MERR_ENCMISMATCH:
1036-
if (!instruction->prefixes[PPS_REX]) {
1037-
nasm_nonfatal("instruction not encodable without explicit prefix");
1038-
} else {
1039-
nasm_nonfatal("instruction not encodable with %s prefix",
1040-
prefix_name(instruction->prefixes[PPS_REX]));
1041-
}
1042-
break;
1043-
case MERR_BADBND:
1044-
case MERR_BADREPNE:
1045-
nasm_nonfatal("%s prefix is not allowed",
1046-
prefix_name(instruction->prefixes[PPS_REP]));
1047-
break;
1048-
case MERR_REGSETSIZE:
1049-
nasm_nonfatal("invalid register set size");
1050-
break;
1051-
case MERR_REGSET:
1052-
nasm_nonfatal("register set not valid for operand");
1053-
break;
1054-
case MERR_WRONGIMM:
1055-
nasm_nonfatal("operand/operator invalid for this instruction");
1056-
break;
1057-
case MERR_BADZU:
1058-
nasm_nonfatal("{zu} not applicable to this instruction");
1059-
break;
1060-
case MERR_MEMZU:
1061-
nasm_nonfatal("{zu} invalid for non-register destination");
1062-
break;
1063-
case MERR_BADNF:
1064-
nasm_nonfatal("{nf} not available for this instruction");
1065-
break;
1066-
case MERR_REQNF:
1067-
nasm_nonfatal("{nf} required for this instruction");
1068-
break;
1069-
}
1070-
1077+
no_match_error(m, instruction);
10711078
instruction->times = 1; /* Avoid repeated error messages */
10721079
}
10731080
}
@@ -1285,8 +1292,10 @@ static int64_t insn_size(insn *instruction)
12851292
insn_early_setup(instruction);
12861293

12871294
m = find_match(&temp, instruction);
1288-
if (m < MOK_GOOD)
1295+
if (m < MOK_GOOD) {
1296+
no_match_error(m, instruction);
12891297
return -1; /* No match */
1298+
}
12901299

12911300
isize = calcsize(instruction, temp);
12921301
debug_set_type(instruction);

travis/test/br3392392.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1+
./travis/test/br3392392.asm:11: error: broadcast not permitted on this operand
2+
./travis/test/br3392392.asm:12: error: broadcast not permitted on this operand
3+
./travis/test/br3392392.asm:13: error: mask not permitted on this operand
14
./travis/test/br3392392.asm:14: error: broadcast not allowed with register operand

travis/test/br3392531.stderr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
./travis/test/br3392531.asm:5: error: instruction expected, found `&'
55
./travis/test/br3392531.asm:7: error: `%macro' expects a parameter count
66
./travis/test/br3392531.asm:11: warning: unterminated string (missing ``') [-w+pp-open-string]
7-
./travis/test/br3392531.asm:14: error: instruction expected, found `� %'
7+
./travis/test/br3392531.asm:14: error: instruction expected, found `� %'
8+
./travis/test/br3392531.asm:16: error: invalid combination of opcode and operands
89
./travis/test/br3392531.asm:17: error: `%$LRG': context stack is empty
910
./travis/test/br3392531.asm:17: error: `%$LRG': context stack is empty
1011
./travis/test/br3392531.asm:17: error: label, instruction or prefix expected at start of line, found `%'

travis/test/vex1.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
./travis/test/vex.asm:29: error: instruction not encodable with {vex2} prefix
22
./travis/test/vex.asm:30: error: cannot use high byte register in this instruction
33
./travis/test/vex.asm:32: error: invalid operands in 32-bit mode
4+
./travis/test/vex.asm:35: error: instruction not encodable with {rex} prefix
5+
./travis/test/vex.asm:36: error: instruction not encodable with {vex} prefix
6+
./travis/test/vex.asm:37: error: instruction not encodable with {vex3} prefix

0 commit comments

Comments
 (0)