Add architecture normalization

ober

056a56942f0932c331ed9f5c3e72fb3d193103cd

diff --git a/lib/jasm/disasm.ss b/lib/jasm/disasm.ss
index 3281936..9f6bc78 100644
--- a/lib/jasm/disasm.ss
+++ b/lib/jasm/disasm.ss
@@ -3,6 +3,8 @@
 (library (jasm disasm)
   (export
     supported-architectures
+    normalize-architecture
+    architecture-endianness
     hex-string->bytevector
     disassemble-bytevector
     disassemble->string
@@ -16,7 +18,39 @@
 
   (import (chezscheme))
 
-  (define supported-architectures '(x86-64 aarch64))
+  (define supported-architectures '(x86-64 aarch64 mips mipsel mips64 mips64el))
+
+  (define architecture-aliases
+    '((x86-64 . x86-64)
+      (x86_64 . x86-64)
+      (amd64 . x86-64)
+      (aarch64 . aarch64)
+      (arm64 . aarch64)
+      (mips . mips)
+      (mips32 . mips)
+      (mipseb . mips)
+      (mips32eb . mips)
+      (mipsel . mipsel)
+      (mips32el . mipsel)
+      (mips64 . mips64)
+      (mips64eb . mips64)
+      (mips64el . mips64el)))
+
+  (define (normalize-architecture arch)
+    (let* ([sym (cond
+                  [(symbol? arch) arch]
+                  [(string? arch) (string->symbol arch)]
+                  [else (error 'normalize-architecture "architecture must be a symbol or string" arch)])]
+           [cell (assq sym architecture-aliases)])
+      (if cell
+          (cdr cell)
+          (error 'normalize-architecture "unsupported architecture" arch))))
+
+  (define (architecture-endianness arch)
+    (case (normalize-architecture arch)
+      [(mips mips64) 'big]
+      [(mipsel mips64el) 'little]
+      [else 'little]))
 
   (define (instruction? x)
     (and (pair? x) (eq? (car x) 'instruction)))
@@ -337,13 +371,14 @@
               [else (a64-unknown-word bv offset address remaining)])))))
 
   (define (decode-instruction arch bv offset address options)
-    (cond
-      [(eq? arch 'x86-64) (decode-x86-64 bv offset address options)]
-      [(eq? arch 'aarch64) (decode-aarch64 bv offset address options)]
-      [else (error 'decode-instruction "unsupported architecture" arch)]))
+    (case (normalize-architecture arch)
+      [(x86-64) (decode-x86-64 bv offset address options)]
+      [(aarch64) (decode-aarch64 bv offset address options)]
+      [else (error 'decode-instruction "decoder not implemented for architecture" arch)]))
 
   (define (disassemble-bytevector arch bv . maybe-options)
-    (let* ([options (if (null? maybe-options) '() (car maybe-options))]
+    (let* ([arch (normalize-architecture arch)]
+           [options (if (null? maybe-options) '() (car maybe-options))]
            [base (option-ref options 'address 0)]
            [len (bytevector-length bv)])
       (let loop ([offset 0] [address base] [out '()])
diff --git a/main.ss b/main.ss
index f12871c..3591252 100644
--- a/main.ss
+++ b/main.ss
@@ -4,18 +4,13 @@
 
 (define (usage)
   (display "Usage:\n")
-  (display "  jasm raw --arch <x86-64|aarch64> [--syntax att|intel] [--address n] --hex <bytes>\n")
+  (display "  jasm raw --arch <x86-64|aarch64|mips|mipsel|mips64|mips64el> [--syntax att|intel] [--address n] --hex <bytes>\n")
   (display "\nExamples:\n")
   (display "  jasm raw --arch x86-64 --syntax intel --hex '55 48 89 e5 c3'\n")
   (display "  jasm raw --arch aarch64 --hex '20 00 80 d2 c0 03 5f d6'\n"))
 
 (define (string->arch s)
-  (cond
-    [(string=? s "x86-64") 'x86-64]
-    [(string=? s "x86_64") 'x86-64]
-    [(string=? s "aarch64") 'aarch64]
-    [(string=? s "arm64") 'aarch64]
-    [else (error 'jasm "unsupported architecture" s)]))
+  (normalize-architecture s))
 
 (define (parse-number s)
   (let ([n (string->number s 0)])
diff --git a/tests/test-jasm.ss b/tests/test-jasm.ss
index 9625538..82da8cd 100644
--- a/tests/test-jasm.ss
+++ b/tests/test-jasm.ss
@@ -32,6 +32,19 @@
   (bytevector->u8-list (hex-string->bytevector "0x55, 48:89_e5"))
   '(85 72 137 229))
 
+(test "normalize architecture x86_64"
+  (normalize-architecture "x86_64")
+  'x86-64)
+
+(test "normalize architecture mips32el"
+  (normalize-architecture 'mips32el)
+  'mipsel)
+
+(test "architecture endianness"
+  (list (architecture-endianness 'mips)
+        (architecture-endianness 'mips64el))
+  '(big little))
+
 (test "x86 push att"
   (one-text 'x86-64 "55")
   "pushq\t%rbp")