about summary refs log tree commit diff stats
path: root/subx/023check_operand_sizes.cc
diff options
context:
space:
mode:
Diffstat (limited to 'subx/023check_operand_sizes.cc')
-rw-r--r--subx/023check_operand_sizes.cc81
1 files changed, 15 insertions, 66 deletions
diff --git a/subx/023check_operand_sizes.cc b/subx/023check_operand_sizes.cc
index 5d2ec456..cec625af 100644
--- a/subx/023check_operand_sizes.cc
+++ b/subx/023check_operand_sizes.cc
@@ -37,26 +37,25 @@ void check_operand_bounds(/*const*/ program& p) {
 }
 
 void check_operand_bounds(const word& w) {
-  for (map<string, uint32_t>::iterator p = Operand_bound.begin();  p != Operand_bound.end();  ++p)
-    if (has_metadata(w, p->first))
-      if (parse_int(w.data) >= p->second)
-        raise << "'" << w.original << "' too large to fit in bitfield " << p->first << '\n' << end();
-}
-
-int first_operand(const line& inst) {
-  if (inst.words.at(0).data == "0f") return 2;
-  if (inst.words.at(0).data == "f3") {
-    if (inst.words.at(1).data == "0f")
-      return 3;
-    else
-      return 2;
+  for (map<string, uint32_t>::iterator p = Operand_bound.begin();  p != Operand_bound.end();  ++p) {
+    if (has_metadata(w, p->first)) {
+      int32_t x = parse_int(w.data);
+      if (x >= 0) {
+        if (static_cast<uint32_t>(x) >= p->second)
+          raise << "'" << w.original << "' too large to fit in bitfield " << p->first << '\n' << end();
+      }
+      else {
+        // hacky? assuming bound is a power of 2
+        if (x < -1*static_cast<int32_t>(p->second/2))
+          raise << "'" << w.original << "' too large to fit in bitfield " << p->first << '\n' << end();
+      }
+    }
   }
-  return 1;
 }
 
-uint32_t parse_int(const string& s) {
+int32_t parse_int(const string& s) {
   istringstream in(s);
-  uint32_t result = 0;
+  int32_t result = 0;
   if (starts_with(s, "0x"))
     in >> std::hex;
   in >> result;
@@ -66,53 +65,3 @@ uint32_t parse_int(const string& s) {
   }
   return result;
 }
-
-void check_metadata_present(const line& inst, const string& type, uint8_t op) {
-  if (!has_metadata(inst, type))
-    raise << "'" << to_string(inst) << "' (" << get(name, op) << "): missing " << type << " operand\n" << end();
-}
-
-bool has_metadata(const line& inst, const string& m) {
-  bool result = false;
-  for (int i = 0;  i < SIZE(inst.words);  ++i) {
-    if (!has_metadata(inst.words.at(i), m)) continue;
-    if (result) {
-      raise << "'" << to_string(inst) << "' has conflicting " << m << " operands\n" << end();
-      return false;
-    }
-    result = true;
-  }
-  return result;
-}
-
-bool has_metadata(const word& w, const string& m) {
-  bool result = false;
-  bool metadata_found = false;
-  for (int i = 0;  i < SIZE(w.metadata);  ++i) {
-    const string& curr = w.metadata.at(i);
-    if (!contains_key(Operand_bound, curr)) continue;  // ignore unrecognized metadata
-    if (metadata_found) {
-      raise << "'" << w.original << "' has conflicting operand types; it should have only one\n" << end();
-      return false;
-    }
-    metadata_found = true;
-    result = (curr == m);
-  }
-  return result;
-}
-
-word metadata(const line& inst, const string& m) {
-  for (int i = 0;  i < SIZE(inst.words);  ++i)
-    if (has_metadata(inst.words.at(i), m))
-      return inst.words.at(i);
-  assert(false);
-}
-
-string to_string(const line& inst) {
-  ostringstream out;
-  for (int i = 0;  i < SIZE(inst.words);  ++i) {
-    if (i > 0) out << ' ';
-    out << inst.words.at(i).original;
-  }
-  return out.str();
-}