about summary refs log tree commit diff stats
path: root/033check_operands.cc
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-09-27 22:05:11 -0700
committerKartik Agaram <vc@akkartik.com>2020-09-27 22:05:11 -0700
commiteee09a56076f40beabea1f9f677d7d6463265bb0 (patch)
treec3bc8d12e48b671d36f31befb5ea9e07486f13d0 /033check_operands.cc
parentf068bda98e0218df6b551a6cd8e5520255866308 (diff)
downloadmu-eee09a56076f40beabea1f9f677d7d6463265bb0.tar.gz
6887
subx.md distinguishes between operands and arguments. Let's use that terminology
more consistently in the sources.
Diffstat (limited to '033check_operands.cc')
-rw-r--r--033check_operands.cc452
1 files changed, 226 insertions, 226 deletions
diff --git a/033check_operands.cc b/033check_operands.cc
index 7d73c97f..e6f71094 100644
--- a/033check_operands.cc
+++ b/033check_operands.cc
@@ -1,41 +1,41 @@
-//: Since we're tagging operands with their types, let's start checking these
-//: operand types for each instruction.
+//: Since we're tagging arguments with their types, let's start checking these
+//: argument types for each instruction.
 
-void test_check_missing_imm8_operand() {
+void test_check_missing_imm8_argument() {
   Hide_errors = true;
   run(
       "== code 0x1\n"
       "cd\n"  // interrupt ??
   );
   CHECK_TRACE_CONTENTS(
-      "error: 'cd' (software interrupt): missing imm8 operand\n"
+      "error: 'cd' (software interrupt): missing imm8 argument\n"
   );
 }
 
 :(before "Pack Operands(segment code)")
-check_operands(code);
+check_arguments(code);
 if (trace_contains_errors()) return;
 
 :(code)
-void check_operands(const segment& code) {
-  trace(3, "transform") << "-- check operands" << end();
+void check_arguments(const segment& code) {
+  trace(3, "transform") << "-- check arguments" << end();
   for (int i = 0;  i < SIZE(code.lines);  ++i) {
-    check_operands(code.lines.at(i));
+    check_arguments(code.lines.at(i));
     if (trace_contains_errors()) return;  // stop at the first mal-formed instruction
   }
 }
 
-void check_operands(const line& inst) {
+void check_arguments(const line& inst) {
   word op = preprocess_op(inst.words.at(0));
   if (op.data == "0f") {
-    check_operands_0f(inst);
+    check_arguments_0f(inst);
     return;
   }
   if (op.data == "f3") {
-    check_operands_f3(inst);
+    check_arguments_f3(inst);
     return;
   }
-  check_operands(inst, op);
+  check_arguments(inst, op);
 }
 
 word preprocess_op(word/*copy*/ op) {
@@ -54,17 +54,17 @@ void test_preprocess_op() {
   CHECK_EQ(preprocess_op(w1).data, preprocess_op(w2).data);
 }
 
-//: To check the operands for an opcode, we'll track the permitted operands
+//: To check the arguments for an opcode, we'll track the permitted arguments
 //: for each supported opcode in a bitvector. That way we can often compute the
-//: 'received' operand bitvector for each instruction's operands and compare
+//: 'received' argument bitvector for each instruction's arguments and compare
 //: it with the 'expected' bitvector.
 //:
 //: The 'expected' and 'received' bitvectors can be different; the MODRM bit
-//: in the 'expected' bitvector maps to multiple 'received' operand types in
+//: in the 'expected' bitvector maps to multiple 'received' argument types in
 //: an instruction. We deal in expected bitvectors throughout.
 
 :(before "End Types")
-enum expected_operand_type {
+enum expected_argument_type {
   // start from the least significant bit
   MODRM,  // more complex, may also involve disp8 or disp32
   SUBOP,
@@ -77,7 +77,7 @@ enum expected_operand_type {
 };
 :(before "End Globals")
 vector<string> Operand_type_name;
-map<string, expected_operand_type> Operand_type;
+map<string, expected_argument_type> Operand_type;
 :(before "End One-time Setup")
 init_op_types();
 :(code)
@@ -96,160 +96,160 @@ void init_op_types() {
 }
 
 :(before "End Globals")
-map</*op*/string, /*bitvector*/uint8_t> Permitted_operands;
-const uint8_t INVALID_OPERANDS = 0xff;  // no instruction uses all the operand types
+map</*op*/string, /*bitvector*/uint8_t> Permitted_arguments;
+const uint8_t INVALID_OPERANDS = 0xff;  // no instruction uses all the argument types
 :(before "End One-time Setup")
-init_permitted_operands();
+init_permitted_arguments();
 :(code)
-void init_permitted_operands() {
-  //// Class A: just op, no operands
+void init_permitted_arguments() {
+  //// Class A: just op, no arguments
   // halt
-  put(Permitted_operands, "f4", 0x00);
+  put(Permitted_arguments, "f4", 0x00);
   // inc
-  put(Permitted_operands, "40", 0x00);
-  put(Permitted_operands, "41", 0x00);
-  put(Permitted_operands, "42", 0x00);
-  put(Permitted_operands, "43", 0x00);
-  put(Permitted_operands, "44", 0x00);
-  put(Permitted_operands, "45", 0x00);
-  put(Permitted_operands, "46", 0x00);
-  put(Permitted_operands, "47", 0x00);
+  put(Permitted_arguments, "40", 0x00);
+  put(Permitted_arguments, "41", 0x00);
+  put(Permitted_arguments, "42", 0x00);
+  put(Permitted_arguments, "43", 0x00);
+  put(Permitted_arguments, "44", 0x00);
+  put(Permitted_arguments, "45", 0x00);
+  put(Permitted_arguments, "46", 0x00);
+  put(Permitted_arguments, "47", 0x00);
   // dec
-  put(Permitted_operands, "48", 0x00);
-  put(Permitted_operands, "49", 0x00);
-  put(Permitted_operands, "4a", 0x00);
-  put(Permitted_operands, "4b", 0x00);
-  put(Permitted_operands, "4c", 0x00);
-  put(Permitted_operands, "4d", 0x00);
-  put(Permitted_operands, "4e", 0x00);
-  put(Permitted_operands, "4f", 0x00);
+  put(Permitted_arguments, "48", 0x00);
+  put(Permitted_arguments, "49", 0x00);
+  put(Permitted_arguments, "4a", 0x00);
+  put(Permitted_arguments, "4b", 0x00);
+  put(Permitted_arguments, "4c", 0x00);
+  put(Permitted_arguments, "4d", 0x00);
+  put(Permitted_arguments, "4e", 0x00);
+  put(Permitted_arguments, "4f", 0x00);
   // push
-  put(Permitted_operands, "50", 0x00);
-  put(Permitted_operands, "51", 0x00);
-  put(Permitted_operands, "52", 0x00);
-  put(Permitted_operands, "53", 0x00);
-  put(Permitted_operands, "54", 0x00);
-  put(Permitted_operands, "55", 0x00);
-  put(Permitted_operands, "56", 0x00);
-  put(Permitted_operands, "57", 0x00);
+  put(Permitted_arguments, "50", 0x00);
+  put(Permitted_arguments, "51", 0x00);
+  put(Permitted_arguments, "52", 0x00);
+  put(Permitted_arguments, "53", 0x00);
+  put(Permitted_arguments, "54", 0x00);
+  put(Permitted_arguments, "55", 0x00);
+  put(Permitted_arguments, "56", 0x00);
+  put(Permitted_arguments, "57", 0x00);
   // pop
-  put(Permitted_operands, "58", 0x00);
-  put(Permitted_operands, "59", 0x00);
-  put(Permitted_operands, "5a", 0x00);
-  put(Permitted_operands, "5b", 0x00);
-  put(Permitted_operands, "5c", 0x00);
-  put(Permitted_operands, "5d", 0x00);
-  put(Permitted_operands, "5e", 0x00);
-  put(Permitted_operands, "5f", 0x00);
+  put(Permitted_arguments, "58", 0x00);
+  put(Permitted_arguments, "59", 0x00);
+  put(Permitted_arguments, "5a", 0x00);
+  put(Permitted_arguments, "5b", 0x00);
+  put(Permitted_arguments, "5c", 0x00);
+  put(Permitted_arguments, "5d", 0x00);
+  put(Permitted_arguments, "5e", 0x00);
+  put(Permitted_arguments, "5f", 0x00);
   // sign-extend EAX into EDX
-  put(Permitted_operands, "99", 0x00);
+  put(Permitted_arguments, "99", 0x00);
   // return
-  put(Permitted_operands, "c3", 0x00);
+  put(Permitted_arguments, "c3", 0x00);
 
   //// Class B: just op and disp8
   //  imm32 imm8  disp32 |disp16  disp8 subop modrm
   //  0     0     0      |0       1     0     0
 
   // jump
-  put(Permitted_operands, "eb", 0x04);
-  put(Permitted_operands, "72", 0x04);
-  put(Permitted_operands, "73", 0x04);
-  put(Permitted_operands, "74", 0x04);
-  put(Permitted_operands, "75", 0x04);
-  put(Permitted_operands, "76", 0x04);
-  put(Permitted_operands, "77", 0x04);
-  put(Permitted_operands, "7c", 0x04);
-  put(Permitted_operands, "7d", 0x04);
-  put(Permitted_operands, "7e", 0x04);
-  put(Permitted_operands, "7f", 0x04);
+  put(Permitted_arguments, "eb", 0x04);
+  put(Permitted_arguments, "72", 0x04);
+  put(Permitted_arguments, "73", 0x04);
+  put(Permitted_arguments, "74", 0x04);
+  put(Permitted_arguments, "75", 0x04);
+  put(Permitted_arguments, "76", 0x04);
+  put(Permitted_arguments, "77", 0x04);
+  put(Permitted_arguments, "7c", 0x04);
+  put(Permitted_arguments, "7d", 0x04);
+  put(Permitted_arguments, "7e", 0x04);
+  put(Permitted_arguments, "7f", 0x04);
 
   //// Class D: just op and disp32
   //  imm32 imm8  disp32 |disp16  disp8 subop modrm
   //  0     0     1      |0       0     0     0
-  put(Permitted_operands, "e8", 0x10);  // call
-  put(Permitted_operands, "e9", 0x10);  // jump
+  put(Permitted_arguments, "e8", 0x10);  // call
+  put(Permitted_arguments, "e9", 0x10);  // jump
 
   //// Class E: just op and imm8
   //  imm32 imm8  disp32 |disp16  disp8 subop modrm
   //  0     1     0      |0       0     0     0
-  put(Permitted_operands, "cd", 0x20);  // software interrupt
+  put(Permitted_arguments, "cd", 0x20);  // software interrupt
 
   //// Class F: just op and imm32
   //  imm32 imm8  disp32 |disp16  disp8 subop modrm
   //  1     0     0      |0       0     0     0
-  put(Permitted_operands, "05", 0x40);  // add
-  put(Permitted_operands, "2d", 0x40);  // subtract
-  put(Permitted_operands, "25", 0x40);  // and
-  put(Permitted_operands, "0d", 0x40);  // or
-  put(Permitted_operands, "35", 0x40);  // xor
-  put(Permitted_operands, "3d", 0x40);  // compare
-  put(Permitted_operands, "68", 0x40);  // push
+  put(Permitted_arguments, "05", 0x40);  // add
+  put(Permitted_arguments, "2d", 0x40);  // subtract
+  put(Permitted_arguments, "25", 0x40);  // and
+  put(Permitted_arguments, "0d", 0x40);  // or
+  put(Permitted_arguments, "35", 0x40);  // xor
+  put(Permitted_arguments, "3d", 0x40);  // compare
+  put(Permitted_arguments, "68", 0x40);  // push
   // copy
-  put(Permitted_operands, "b8", 0x40);
-  put(Permitted_operands, "b9", 0x40);
-  put(Permitted_operands, "ba", 0x40);
-  put(Permitted_operands, "bb", 0x40);
-  put(Permitted_operands, "bc", 0x40);
-  put(Permitted_operands, "bd", 0x40);
-  put(Permitted_operands, "be", 0x40);
-  put(Permitted_operands, "bf", 0x40);
+  put(Permitted_arguments, "b8", 0x40);
+  put(Permitted_arguments, "b9", 0x40);
+  put(Permitted_arguments, "ba", 0x40);
+  put(Permitted_arguments, "bb", 0x40);
+  put(Permitted_arguments, "bc", 0x40);
+  put(Permitted_arguments, "bd", 0x40);
+  put(Permitted_arguments, "be", 0x40);
+  put(Permitted_arguments, "bf", 0x40);
 
   //// Class M: using ModR/M byte
   //  imm32 imm8  disp32 |disp16  disp8 subop modrm
   //  0     0     0      |0       0     0     1
 
   // add
-  put(Permitted_operands, "01", 0x01);
-  put(Permitted_operands, "03", 0x01);
+  put(Permitted_arguments, "01", 0x01);
+  put(Permitted_arguments, "03", 0x01);
   // subtract
-  put(Permitted_operands, "29", 0x01);
-  put(Permitted_operands, "2b", 0x01);
+  put(Permitted_arguments, "29", 0x01);
+  put(Permitted_arguments, "2b", 0x01);
   // and
-  put(Permitted_operands, "21", 0x01);
-  put(Permitted_operands, "23", 0x01);
+  put(Permitted_arguments, "21", 0x01);
+  put(Permitted_arguments, "23", 0x01);
   // or
-  put(Permitted_operands, "09", 0x01);
-  put(Permitted_operands, "0b", 0x01);
+  put(Permitted_arguments, "09", 0x01);
+  put(Permitted_arguments, "0b", 0x01);
   // xor
-  put(Permitted_operands, "31", 0x01);
-  put(Permitted_operands, "33", 0x01);
+  put(Permitted_arguments, "31", 0x01);
+  put(Permitted_arguments, "33", 0x01);
   // compare
-  put(Permitted_operands, "39", 0x01);
-  put(Permitted_operands, "3b", 0x01);
+  put(Permitted_arguments, "39", 0x01);
+  put(Permitted_arguments, "3b", 0x01);
   // copy
-  put(Permitted_operands, "88", 0x01);
-  put(Permitted_operands, "89", 0x01);
-  put(Permitted_operands, "8a", 0x01);
-  put(Permitted_operands, "8b", 0x01);
+  put(Permitted_arguments, "88", 0x01);
+  put(Permitted_arguments, "89", 0x01);
+  put(Permitted_arguments, "8a", 0x01);
+  put(Permitted_arguments, "8b", 0x01);
   // swap
-  put(Permitted_operands, "87", 0x01);
+  put(Permitted_arguments, "87", 0x01);
   // copy address (lea)
-  put(Permitted_operands, "8d", 0x01);
+  put(Permitted_arguments, "8d", 0x01);
 
   //// Class N: op, ModR/M and subop (not r32)
   //  imm32 imm8  disp32 |disp16  disp8 subop modrm
   //  0     0     0      |0       0     1     1
-  put(Permitted_operands, "8f", 0x03);  // pop
-  put(Permitted_operands, "d3", 0x03);  // shift
-  put(Permitted_operands, "f7", 0x03);  // test/not/mul/div
-  put(Permitted_operands, "ff", 0x03);  // jump/push/call
+  put(Permitted_arguments, "8f", 0x03);  // pop
+  put(Permitted_arguments, "d3", 0x03);  // shift
+  put(Permitted_arguments, "f7", 0x03);  // test/not/mul/div
+  put(Permitted_arguments, "ff", 0x03);  // jump/push/call
 
   //// Class O: op, ModR/M, subop (not r32) and imm8
   //  imm32 imm8  disp32 |disp16  disp8 subop modrm
   //  0     1     0      |0       0     1     1
-  put(Permitted_operands, "c1", 0x23);  // combine
-  put(Permitted_operands, "c6", 0x23);  // copy
+  put(Permitted_arguments, "c1", 0x23);  // combine
+  put(Permitted_arguments, "c6", 0x23);  // copy
 
   //// Class P: op, ModR/M, subop (not r32) and imm32
   //  imm32 imm8  disp32 |disp16  disp8 subop modrm
   //  1     0     0      |0       0     1     1
-  put(Permitted_operands, "81", 0x43);  // combine
-  put(Permitted_operands, "c7", 0x43);  // copy
+  put(Permitted_arguments, "81", 0x43);  // combine
+  put(Permitted_arguments, "c7", 0x43);  // copy
 
   //// Class Q: op, ModR/M and imm32
   //  imm32 imm8  disp32 |disp16  disp8 subop modrm
   //  1     0     0      |0       0     0     1
-  put(Permitted_operands, "69", 0x41);  // multiply
+  put(Permitted_arguments, "69", 0x41);  // multiply
 
   // End Init Permitted Operands
 }
@@ -258,11 +258,11 @@ void init_permitted_operands() {
 #define SET(bitvector, bit)  ((bitvector) | (1 << (bit)))
 #define CLEAR(bitvector, bit)  ((bitvector) & (~(1 << (bit))))
 
-void check_operands(const line& inst, const word& op) {
+void check_arguments(const line& inst, const word& op) {
   if (!is_hex_byte(op)) return;
-  uint8_t expected_bitvector = get(Permitted_operands, op.data);
+  uint8_t expected_bitvector = get(Permitted_arguments, op.data);
   if (HAS(expected_bitvector, MODRM)) {
-    check_operands_modrm(inst, op);
+    check_arguments_modrm(inst, op);
     compare_bitvector_modrm(inst, expected_bitvector, maybe_name(op));
   }
   else {
@@ -273,18 +273,18 @@ void check_operands(const line& inst, const word& op) {
 //: Many instructions can be checked just by comparing bitvectors.
 
 void compare_bitvector(const line& inst, uint8_t expected, const string& maybe_op_name) {
-  if (all_hex_bytes(inst) && has_operands(inst)) return;  // deliberately programming in raw hex; we'll raise a warning elsewhere
-  uint8_t bitvector = compute_expected_operand_bitvector(inst);
-  if (trace_contains_errors()) return;  // duplicate operand type
+  if (all_hex_bytes(inst) && has_arguments(inst)) return;  // deliberately programming in raw hex; we'll raise a warning elsewhere
+  uint8_t bitvector = compute_expected_argument_bitvector(inst);
+  if (trace_contains_errors()) return;  // duplicate argument type
   if (bitvector == expected) return;  // all good with this instruction
   for (int i = 0;  i < NUM_OPERAND_TYPES;  ++i, bitvector >>= 1, expected >>= 1) {
 //?     cerr << "comparing " << HEXBYTE << NUM(bitvector) << " with " << NUM(expected) << '\n';
-    if ((bitvector & 0x1) == (expected & 0x1)) continue;  // all good with this operand
+    if ((bitvector & 0x1) == (expected & 0x1)) continue;  // all good with this argument
     const string& optype = Operand_type_name.at(i);
     if ((bitvector & 0x1) > (expected & 0x1))
-      raise << "'" << to_string(inst) << "'" << maybe_op_name << ": unexpected " << optype << " operand\n" << end();
+      raise << "'" << to_string(inst) << "'" << maybe_op_name << ": unexpected " << optype << " argument\n" << end();
     else
-      raise << "'" << to_string(inst) << "'" << maybe_op_name << ": missing " << optype << " operand\n" << end();
+      raise << "'" << to_string(inst) << "'" << maybe_op_name << ": missing " << optype << " argument\n" << end();
     // continue giving all errors for a single instruction
   }
   // ignore settings in any unused bits
@@ -298,21 +298,21 @@ string maybe_name(const word& op) {
   return " ("+s.substr(0, s.find(" ("))+')';
 }
 
-uint32_t compute_expected_operand_bitvector(const line& inst) {
-  set<string> operands_found;
+uint32_t compute_expected_argument_bitvector(const line& inst) {
+  set<string> arguments_found;
   uint32_t bitvector = 0;
   for (int i = /*skip op*/1;  i < SIZE(inst.words);  ++i) {
-    bitvector = bitvector | expected_bit_for_received_operand(inst.words.at(i), operands_found, inst);
-    if (trace_contains_errors()) return INVALID_OPERANDS;  // duplicate operand type
+    bitvector = bitvector | expected_bit_for_received_argument(inst.words.at(i), arguments_found, inst);
+    if (trace_contains_errors()) return INVALID_OPERANDS;  // duplicate argument type
   }
   return bitvector;
 }
 
-bool has_operands(const line& inst) {
-  return SIZE(inst.words) > first_operand(inst);
+bool has_arguments(const line& inst) {
+  return SIZE(inst.words) > first_argument(inst);
 }
 
-int first_operand(const line& inst) {
+int first_argument(const line& inst) {
   if (inst.words.at(0).data == "0f") return 2;
   if (inst.words.at(0).data == "f2" || inst.words.at(0).data == "f3") {
     if (inst.words.at(1).data == "0f")
@@ -323,9 +323,9 @@ int first_operand(const line& inst) {
   return 1;
 }
 
-// Scan the metadata of 'w' and return the expected bit corresponding to any operand type.
-// Also raise an error if metadata contains multiple operand types.
-uint32_t expected_bit_for_received_operand(const word& w, set<string>& instruction_operands, const line& inst) {
+// Scan the metadata of 'w' and return the expected bit corresponding to any argument type.
+// Also raise an error if metadata contains multiple argument types.
+uint32_t expected_bit_for_received_argument(const word& w, set<string>& instruction_arguments, const line& inst) {
   uint32_t bv = 0;
   bool found = false;
   for (int i = 0;  i < SIZE(w.metadata);  ++i) {
@@ -335,65 +335,65 @@ uint32_t expected_bit_for_received_operand(const word& w, set<string>& instructi
       expected_metadata = "modrm";
     else if (!contains_key(Operand_type, curr)) continue;  // ignore unrecognized metadata
     if (found) {
-      raise << "'" << w.original << "' has conflicting operand types; it should have only one\n" << end();
+      raise << "'" << w.original << "' has conflicting argument types; it should have only one\n" << end();
       return INVALID_OPERANDS;
     }
-    if (instruction_operands.find(curr) != instruction_operands.end()) {
-      raise << "'" << to_string(inst) << "': duplicate " << curr << " operand\n" << end();
+    if (instruction_arguments.find(curr) != instruction_arguments.end()) {
+      raise << "'" << to_string(inst) << "': duplicate " << curr << " argument\n" << end();
       return INVALID_OPERANDS;
     }
-    instruction_operands.insert(curr);
+    instruction_arguments.insert(curr);
     bv = (1 << get(Operand_type, expected_metadata));
     found = true;
   }
   return bv;
 }
 
-void test_conflicting_operand_type() {
+void test_conflicting_argument_type() {
   Hide_errors = true;
   run(
       "== code 0x1\n"
       "cd/software-interrupt 80/imm8/imm32\n"
   );
   CHECK_TRACE_CONTENTS(
-      "error: '80/imm8/imm32' has conflicting operand types; it should have only one\n"
+      "error: '80/imm8/imm32' has conflicting argument types; it should have only one\n"
   );
 }
 
 //: Instructions computing effective addresses have more complex rules, so
 //: we'll hard-code a common set of instruction-decoding rules.
 
-void test_check_missing_mod_operand() {
+void test_check_missing_mod_argument() {
   Hide_errors = true;
   run(
       "== code 0x1\n"
       "81 0/add/subop       3/rm32/ebx 1/imm32\n"
   );
   CHECK_TRACE_CONTENTS(
-      "error: '81 0/add/subop 3/rm32/ebx 1/imm32' (combine rm32 with imm32 based on subop): missing mod operand\n"
+      "error: '81 0/add/subop 3/rm32/ebx 1/imm32' (combine rm32 with imm32 based on subop): missing mod argument\n"
   );
 }
 
-void check_operands_modrm(const line& inst, const word& op) {
+void check_arguments_modrm(const line& inst, const word& op) {
   if (all_hex_bytes(inst)) return;  // deliberately programming in raw hex; we'll raise a warning elsewhere
-  check_operand_metadata_present(inst, "mod", op);
-  check_operand_metadata_present(inst, "rm32", op);
+  check_argument_metadata_present(inst, "mod", op);
+  check_argument_metadata_present(inst, "rm32", op);
   // no check for r32; some instructions don't use it; just assume it's 0 if missing
   if (op.data == "81" || op.data == "8f" || op.data == "f7" || op.data == "ff") {  // keep sync'd with 'help subop'
-    check_operand_metadata_present(inst, "subop", op);
-    check_operand_metadata_absent(inst, "r32", op, "should be replaced by subop");
+    check_argument_metadata_present(inst, "subop", op);
+    check_argument_metadata_absent(inst, "r32", op, "should be replaced by subop");
   }
   if (trace_contains_errors()) return;
   if (metadata(inst, "rm32").data != "4") return;
   // SIB byte checks
   uint8_t mod = hex_byte(metadata(inst, "mod").data);
   if (mod != /*direct*/3) {
-    check_operand_metadata_present(inst, "base", op);
-    check_operand_metadata_present(inst, "index", op);  // otherwise why go to SIB?
+    check_argument_metadata_present(inst, "base", op);
+    check_argument_metadata_present(inst, "index", op);  // otherwise why go to SIB?
   }
   else {
-    check_operand_metadata_absent(inst, "base", op, "direct mode");
-    check_operand_metadata_absent(inst, "index", op, "direct mode");
+    check_argument_metadata_absent(inst, "base", op, "direct mode");
+    check_argument_metadata_absent(inst, "index", op, "direct mode");
   }
   // no check for scale; 0 (2**0 = 1) by default
 }
@@ -401,15 +401,15 @@ void check_operands_modrm(const line& inst, const word& op) {
 // same as compare_bitvector, with one additional exception for modrm-based
 // instructions: they may use an extra displacement on occasion
 void compare_bitvector_modrm(const line& inst, uint8_t expected, const string& maybe_op_name) {
-  if (all_hex_bytes(inst) && has_operands(inst)) return;  // deliberately programming in raw hex; we'll raise a warning elsewhere
-  uint8_t bitvector = compute_expected_operand_bitvector(inst);
-  if (trace_contains_errors()) return;  // duplicate operand type
+  if (all_hex_bytes(inst) && has_arguments(inst)) return;  // deliberately programming in raw hex; we'll raise a warning elsewhere
+  uint8_t bitvector = compute_expected_argument_bitvector(inst);
+  if (trace_contains_errors()) return;  // duplicate argument type
   // update 'expected' bitvector for the additional exception
-  if (has_operand_metadata(inst, "mod")) {
+  if (has_argument_metadata(inst, "mod")) {
     int32_t mod = parse_int(metadata(inst, "mod").data);
     switch (mod) {
     case 0:
-      if (has_operand_metadata(inst, "rm32") && parse_int(metadata(inst, "rm32").data) == 5)
+      if (has_argument_metadata(inst, "rm32") && parse_int(metadata(inst, "rm32").data) == 5)
         expected |= (1<<DISP32);
       break;
     case 1:
@@ -423,25 +423,25 @@ void compare_bitvector_modrm(const line& inst, uint8_t expected, const string& m
   if (bitvector == expected) return;  // all good with this instruction
   for (int i = 0;  i < NUM_OPERAND_TYPES;  ++i, bitvector >>= 1, expected >>= 1) {
 //?     cerr << "comparing for modrm " << HEXBYTE << NUM(bitvector) << " with " << NUM(expected) << '\n';
-    if ((bitvector & 0x1) == (expected & 0x1)) continue;  // all good with this operand
+    if ((bitvector & 0x1) == (expected & 0x1)) continue;  // all good with this argument
     const string& optype = Operand_type_name.at(i);
     if ((bitvector & 0x1) > (expected & 0x1))
-      raise << "'" << to_string(inst) << "'" << maybe_op_name << ": unexpected " << optype << " operand\n" << end();
+      raise << "'" << to_string(inst) << "'" << maybe_op_name << ": unexpected " << optype << " argument\n" << end();
     else
-      raise << "'" << to_string(inst) << "'" << maybe_op_name << ": missing " << optype << " operand\n" << end();
+      raise << "'" << to_string(inst) << "'" << maybe_op_name << ": missing " << optype << " argument\n" << end();
     // continue giving all errors for a single instruction
   }
   // ignore settings in any unused bits
 }
 
-void check_operand_metadata_present(const line& inst, const string& type, const word& op) {
-  if (!has_operand_metadata(inst, type))
-    raise << "'" << to_string(inst) << "'" << maybe_name(op) << ": missing " << type << " operand\n" << end();
+void check_argument_metadata_present(const line& inst, const string& type, const word& op) {
+  if (!has_argument_metadata(inst, type))
+    raise << "'" << to_string(inst) << "'" << maybe_name(op) << ": missing " << type << " argument\n" << end();
 }
 
-void check_operand_metadata_absent(const line& inst, const string& type, const word& op, const string& msg) {
-  if (has_operand_metadata(inst, type))
-    raise << "'" << to_string(inst) << "'" << maybe_name(op) << ": unexpected " << type << " operand (" << msg << ")\n" << end();
+void check_argument_metadata_absent(const line& inst, const string& type, const word& op, const string& msg) {
+  if (has_argument_metadata(inst, type))
+    raise << "'" << to_string(inst) << "'" << maybe_name(op) << ": unexpected " << type << " argument (" << msg << ")\n" << end();
 }
 
 void test_modrm_with_displacement() {
@@ -461,7 +461,7 @@ void test_check_missing_disp8() {
       "89/copy 1/mod/lookup+disp8 0/rm32/EAX 1/r32/ECX\n"  // missing disp8
   );
   CHECK_TRACE_CONTENTS(
-      "error: '89/copy 1/mod/lookup+disp8 0/rm32/EAX 1/r32/ECX' (copy r32 to rm32): missing disp8 operand\n"
+      "error: '89/copy 1/mod/lookup+disp8 0/rm32/EAX 1/r32/ECX' (copy r32 to rm32): missing disp8 argument\n"
   );
 }
 
@@ -472,84 +472,84 @@ void test_check_missing_disp32() {
       "8b/copy 0/mod/indirect 5/rm32/.disp32 2/r32/EDX\n"  // missing disp32
   );
   CHECK_TRACE_CONTENTS(
-      "error: '8b/copy 0/mod/indirect 5/rm32/.disp32 2/r32/EDX' (copy rm32 to r32): missing disp32 operand\n"
+      "error: '8b/copy 0/mod/indirect 5/rm32/.disp32 2/r32/EDX' (copy rm32 to r32): missing disp32 argument\n"
   );
 }
 
-void test_conflicting_operands_in_modrm_instruction() {
+void test_conflicting_arguments_in_modrm_instruction() {
   Hide_errors = true;
   run(
       "== code 0x1\n"
       "01/add 0/mod 3/mod\n"
   );
   CHECK_TRACE_CONTENTS(
-      "error: '01/add 0/mod 3/mod' has conflicting mod operands\n"
+      "error: '01/add 0/mod 3/mod' has conflicting mod arguments\n"
   );
 }
 
-void test_conflicting_operand_type_modrm() {
+void test_conflicting_argument_type_modrm() {
   Hide_errors = true;
   run(
       "== code 0x1\n"
       "01/add 0/mod 3/rm32/r32\n"
   );
   CHECK_TRACE_CONTENTS(
-      "error: '3/rm32/r32' has conflicting operand types; it should have only one\n"
+      "error: '3/rm32/r32' has conflicting argument types; it should have only one\n"
   );
 }
 
-void test_check_missing_rm32_operand() {
+void test_check_missing_rm32_argument() {
   Hide_errors = true;
   run(
       "== code 0x1\n"
       "81 0/add/subop 0/mod            1/imm32\n"
   );
   CHECK_TRACE_CONTENTS(
-      "error: '81 0/add/subop 0/mod 1/imm32' (combine rm32 with imm32 based on subop): missing rm32 operand\n"
+      "error: '81 0/add/subop 0/mod 1/imm32' (combine rm32 with imm32 based on subop): missing rm32 argument\n"
   );
 }
 
-void test_check_missing_subop_operand() {
+void test_check_missing_subop_argument() {
   Hide_errors = true;
   run(
       "== code 0x1\n"
       "81             0/mod 3/rm32/ebx 1/imm32\n"
   );
   CHECK_TRACE_CONTENTS(
-      "error: '81 0/mod 3/rm32/ebx 1/imm32' (combine rm32 with imm32 based on subop): missing subop operand\n"
+      "error: '81 0/mod 3/rm32/ebx 1/imm32' (combine rm32 with imm32 based on subop): missing subop argument\n"
   );
 }
 
-void test_check_missing_base_operand() {
+void test_check_missing_base_argument() {
   Hide_errors = true;
   run(
       "== code 0x1\n"
       "81 0/add/subop 0/mod/indirect 4/rm32/use-sib 1/imm32\n"
   );
   CHECK_TRACE_CONTENTS(
-      "error: '81 0/add/subop 0/mod/indirect 4/rm32/use-sib 1/imm32' (combine rm32 with imm32 based on subop): missing base operand\n"
+      "error: '81 0/add/subop 0/mod/indirect 4/rm32/use-sib 1/imm32' (combine rm32 with imm32 based on subop): missing base argument\n"
   );
 }
 
-void test_check_missing_index_operand() {
+void test_check_missing_index_argument() {
   Hide_errors = true;
   run(
       "== code 0x1\n"
       "81 0/add/subop 0/mod/indirect 4/rm32/use-sib 0/base 1/imm32\n"
   );
   CHECK_TRACE_CONTENTS(
-      "error: '81 0/add/subop 0/mod/indirect 4/rm32/use-sib 0/base 1/imm32' (combine rm32 with imm32 based on subop): missing index operand\n"
+      "error: '81 0/add/subop 0/mod/indirect 4/rm32/use-sib 0/base 1/imm32' (combine rm32 with imm32 based on subop): missing index argument\n"
   );
 }
 
-void test_check_missing_base_operand_2() {
+void test_check_missing_base_argument_2() {
   Hide_errors = true;
   run(
       "== code 0x1\n"
       "81 0/add/subop 0/mod/indirect 4/rm32/use-sib 2/index 3/scale 1/imm32\n"
   );
   CHECK_TRACE_CONTENTS(
-      "error: '81 0/add/subop 0/mod/indirect 4/rm32/use-sib 2/index 3/scale 1/imm32' (combine rm32 with imm32 based on subop): missing base operand\n"
+      "error: '81 0/add/subop 0/mod/indirect 4/rm32/use-sib 2/index 3/scale 1/imm32' (combine rm32 with imm32 based on subop): missing base argument\n"
   );
 }
 
@@ -560,22 +560,22 @@ void test_check_extra_displacement() {
       "89/copy 0/mod/indirect 0/rm32/EAX 1/r32/ECX 4/disp8\n"
   );
   CHECK_TRACE_CONTENTS(
-      "error: '89/copy 0/mod/indirect 0/rm32/EAX 1/r32/ECX 4/disp8' (copy r32 to rm32): unexpected disp8 operand\n"
+      "error: '89/copy 0/mod/indirect 0/rm32/EAX 1/r32/ECX 4/disp8' (copy r32 to rm32): unexpected disp8 argument\n"
   );
 }
 
-void test_check_duplicate_operand() {
+void test_check_duplicate_argument() {
   Hide_errors = true;
   run(
       "== code 0x1\n"
       "89/copy 0/mod/indirect 0/rm32/EAX 1/r32/ECX 1/r32\n"
   );
   CHECK_TRACE_CONTENTS(
-      "error: '89/copy 0/mod/indirect 0/rm32/EAX 1/r32/ECX 1/r32': duplicate r32 operand\n"
+      "error: '89/copy 0/mod/indirect 0/rm32/EAX 1/r32/ECX 1/r32': duplicate r32 argument\n"
   );
 }
 
-void test_check_base_operand_not_needed_in_direct_mode() {
+void test_check_base_argument_not_needed_in_direct_mode() {
   run(
       "== code 0x1\n"
       "81 0/add/subop 3/mod/indirect 4/rm32/use-sib 1/imm32\n"
@@ -590,13 +590,13 @@ void test_extra_modrm() {
       "59/pop-to-ECX  3/mod/direct 1/rm32/ECX 4/r32/ESP\n"
   );
   CHECK_TRACE_CONTENTS(
-      "error: '59/pop-to-ECX 3/mod/direct 1/rm32/ECX 4/r32/ESP' (pop top of stack to ECX): unexpected modrm operand\n"
+      "error: '59/pop-to-ECX 3/mod/direct 1/rm32/ECX 4/r32/ESP' (pop top of stack to ECX): unexpected modrm argument\n"
   );
 }
 
 //:: similarly handle multi-byte opcodes
 
-void check_operands_0f(const line& inst) {
+void check_arguments_0f(const line& inst) {
   assert(inst.words.at(0).data == "0f");
   if (SIZE(inst.words) == 1) {
     raise << "opcode '0f' requires a second opcode\n" << end();
@@ -607,10 +607,10 @@ void check_operands_0f(const line& inst) {
     raise << "unknown 2-byte opcode '0f " << op.data << "'\n" << end();
     return;
   }
-  check_operands_0f(inst, op);
+  check_arguments_0f(inst, op);
 }
 
-void check_operands_f3(const line& inst) {
+void check_arguments_f3(const line& inst) {
   assert(inst.words.at(0).data == "f3");
   if (SIZE(inst.words) == 1) {
     raise << "opcode 'f3' requires a second opcode\n" << end();
@@ -619,24 +619,24 @@ void check_operands_f3(const line& inst) {
   word op = preprocess_op(inst.words.at(1));
   if (op.data == "0f") {
     word op2 = preprocess_op(inst.words.at(2));
-    check_operands_f3_0f(inst, op2);
+    check_arguments_f3_0f(inst, op2);
     return;
   }
   if (!contains_key(Name_f3, op.data)) {
     raise << "unknown 2-byte opcode 'f3 " << op.data << "'\n" << end();
     return;
   }
-  check_operands_f3(inst, op);
+  check_arguments_f3(inst, op);
 }
 
-void test_check_missing_disp32_operand() {
+void test_check_missing_disp32_argument() {
   Hide_errors = true;
   run(
       "== code 0x1\n"
       "  0f 84  # jmp if ZF to ??\n"
   );
   CHECK_TRACE_CONTENTS(
-      "error: '0f 84' (jump disp32 bytes away if equal, if ZF is set): missing disp32 operand\n"
+      "error: '0f 84' (jump disp32 bytes away if equal, if ZF is set): missing disp32 argument\n"
   );
 }
 
@@ -649,53 +649,53 @@ void test_0f_opcode_with_modrm() {
 }
 
 :(before "End Globals")
-map</*op*/string, /*bitvector*/uint8_t> Permitted_operands_0f;
+map</*op*/string, /*bitvector*/uint8_t> Permitted_arguments_0f;
 :(before "End Init Permitted Operands")
 //// Class D: just op and disp32
 //  imm32 imm8  disp32 |disp16  disp8 subop modrm
 //  0     0     1      |0       0     0     0
-put_new(Permitted_operands_0f, "82", 0x10);
-put_new(Permitted_operands_0f, "83", 0x10);
-put_new(Permitted_operands_0f, "84", 0x10);
-put_new(Permitted_operands_0f, "85", 0x10);
-put_new(Permitted_operands_0f, "86", 0x10);
-put_new(Permitted_operands_0f, "87", 0x10);
-put_new(Permitted_operands_0f, "8c", 0x10);
-put_new(Permitted_operands_0f, "8d", 0x10);
-put_new(Permitted_operands_0f, "8e", 0x10);
-put_new(Permitted_operands_0f, "8f", 0x10);
+put_new(Permitted_arguments_0f, "82", 0x10);
+put_new(Permitted_arguments_0f, "83", 0x10);
+put_new(Permitted_arguments_0f, "84", 0x10);
+put_new(Permitted_arguments_0f, "85", 0x10);
+put_new(Permitted_arguments_0f, "86", 0x10);
+put_new(Permitted_arguments_0f, "87", 0x10);
+put_new(Permitted_arguments_0f, "8c", 0x10);
+put_new(Permitted_arguments_0f, "8d", 0x10);
+put_new(Permitted_arguments_0f, "8e", 0x10);
+put_new(Permitted_arguments_0f, "8f", 0x10);
 
 //// Class M: using ModR/M byte
 //  imm32 imm8  disp32 |disp16  disp8 subop modrm
 //  0     0     0      |0       0     0     1
-put_new(Permitted_operands_0f, "af", 0x01);
+put_new(Permitted_arguments_0f, "af", 0x01);
 // setcc
-put_new(Permitted_operands_0f, "92", 0x01);
-put_new(Permitted_operands_0f, "93", 0x01);
-put_new(Permitted_operands_0f, "94", 0x01);
-put_new(Permitted_operands_0f, "95", 0x01);
-put_new(Permitted_operands_0f, "96", 0x01);
-put_new(Permitted_operands_0f, "97", 0x01);
-put_new(Permitted_operands_0f, "9c", 0x01);
-put_new(Permitted_operands_0f, "9d", 0x01);
-put_new(Permitted_operands_0f, "9e", 0x01);
-put_new(Permitted_operands_0f, "9f", 0x01);
+put_new(Permitted_arguments_0f, "92", 0x01);
+put_new(Permitted_arguments_0f, "93", 0x01);
+put_new(Permitted_arguments_0f, "94", 0x01);
+put_new(Permitted_arguments_0f, "95", 0x01);
+put_new(Permitted_arguments_0f, "96", 0x01);
+put_new(Permitted_arguments_0f, "97", 0x01);
+put_new(Permitted_arguments_0f, "9c", 0x01);
+put_new(Permitted_arguments_0f, "9d", 0x01);
+put_new(Permitted_arguments_0f, "9e", 0x01);
+put_new(Permitted_arguments_0f, "9f", 0x01);
 
 :(before "End Globals")
-map</*op*/string, /*bitvector*/uint8_t> Permitted_operands_f3;
-map</*op*/string, /*bitvector*/uint8_t> Permitted_operands_f3_0f;
+map</*op*/string, /*bitvector*/uint8_t> Permitted_arguments_f3;
+map</*op*/string, /*bitvector*/uint8_t> Permitted_arguments_f3_0f;
 :(before "End Init Permitted Operands")
 //// Class M: using ModR/M byte
 //  imm32 imm8  disp32 |disp16  disp8 subop modrm
 //  0     0     0      |0       0     0     1
-put_new(Permitted_operands_f3_0f, "2a", 0x01);
-put_new(Permitted_operands_f3_0f, "5e", 0x01);
+put_new(Permitted_arguments_f3_0f, "2a", 0x01);
+put_new(Permitted_arguments_f3_0f, "5e", 0x01);
 
 :(code)
-void check_operands_0f(const line& inst, const word& op) {
-  uint8_t expected_bitvector = get(Permitted_operands_0f, op.data);
+void check_arguments_0f(const line& inst, const word& op) {
+  uint8_t expected_bitvector = get(Permitted_arguments_0f, op.data);
   if (HAS(expected_bitvector, MODRM)) {
-    check_operands_modrm(inst, op);
+    check_arguments_modrm(inst, op);
     compare_bitvector_modrm(inst, expected_bitvector, maybe_name_0f(op));
   }
   else {
@@ -703,10 +703,10 @@ void check_operands_0f(const line& inst, const word& op) {
   }
 }
 
-void check_operands_f3(const line& inst, const word& op) {
-  uint8_t expected_bitvector = get(Permitted_operands_f3, op.data);
+void check_arguments_f3(const line& inst, const word& op) {
+  uint8_t expected_bitvector = get(Permitted_arguments_f3, op.data);
   if (HAS(expected_bitvector, MODRM)) {
-    check_operands_modrm(inst, op);
+    check_arguments_modrm(inst, op);
     compare_bitvector_modrm(inst, expected_bitvector, maybe_name_f3(op));
   }
   else {
@@ -714,10 +714,10 @@ void check_operands_f3(const line& inst, const word& op) {
   }
 }
 
-void check_operands_f3_0f(const line& inst, const word& op) {
-  uint8_t expected_bitvector = get(Permitted_operands_f3_0f, op.data);
+void check_arguments_f3_0f(const line& inst, const word& op) {
+  uint8_t expected_bitvector = get(Permitted_arguments_f3_0f, op.data);
   if (HAS(expected_bitvector, MODRM)) {
-    check_operands_modrm(inst, op);
+    check_arguments_modrm(inst, op);
     compare_bitvector_modrm(inst, expected_bitvector, maybe_name_f3_0f(op));
   }
   else {
822'>1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111