about summary refs log tree commit diff stats
path: root/subx/023check_operand_bounds.cc
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-07-27 13:26:12 -0700
committerKartik Agaram <vc@akkartik.com>2018-07-27 13:30:19 -0700
commit071afeff5d99732b2f50f2a5009dc6f2e8303909 (patch)
treec64ab64375bc1d7d79bc6d4022198c9b392bbf87 /subx/023check_operand_bounds.cc
parent4718a77ce26c02bac7cfe28637c2892091ac0075 (diff)
downloadmu-071afeff5d99732b2f50f2a5009dc6f2e8303909.tar.gz
4445 - support labels
Diffstat (limited to 'subx/023check_operand_bounds.cc')
-rw-r--r--subx/023check_operand_bounds.cc30
1 files changed, 19 insertions, 11 deletions
diff --git a/subx/023check_operand_bounds.cc b/subx/023check_operand_bounds.cc
index c868603a..cca4ab24 100644
--- a/subx/023check_operand_bounds.cc
+++ b/subx/023check_operand_bounds.cc
@@ -39,21 +39,29 @@ 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)) {
-      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();
-      }
+    if (!has_metadata(w, p->first)) continue;
+    if (!is_hex_int(w.data)) continue;  // later transforms are on their own to do their own bounds checking
+    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();
     }
   }
 }
 
+bool is_hex_int(const string& s) {
+  if (s.empty()) return false;
+  size_t pos = 0;
+  if (s.at(0) == '-' || s.at(0) == '+') pos++;
+  if (s.substr(pos, pos+2) == "0x") pos += 2;
+  return s.find_first_not_of("0123456789abcdefABCDEF", pos) == string::npos;
+}
+
 int32_t parse_int(const string& s) {
   istringstream in(s);
   int32_t result = 0;