aboutsummaryrefslogtreecommitdiff
path: root/src/cljcc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cljcc')
-rw-r--r--src/cljcc/compiler.clj6
-rw-r--r--src/cljcc/emit.clj10
-rw-r--r--src/cljcc/tacky.clj10
-rw-r--r--src/cljcc/token.clj42
4 files changed, 46 insertions, 22 deletions
diff --git a/src/cljcc/compiler.clj b/src/cljcc/compiler.clj
index cec875b..7d2a93b 100644
--- a/src/cljcc/compiler.clj
+++ b/src/cljcc/compiler.clj
@@ -83,7 +83,8 @@
src2 (tacky-val->assembly-operand (:src2 instruction))
dst (tacky-val->assembly-operand (:dst instruction))
div? (= binop :div)
- mod? (= binop :mod)]
+ mod? (= binop :mod)
+ bit-shift? (contains? #{:bit-right-shift :bit-left-shift} binop)]
(cond
div? [(mov-instruction src1 (reg-operand :ax))
(cdq-instruction)
@@ -93,6 +94,9 @@
(cdq-instruction)
(idiv-instruction src2)
(mov-instruction (reg-operand :dx) dst)]
+ bit-shift? [(mov-instruction src1 dst)
+ (mov-instruction src2 (reg-operand :cx))
+ (binary-instruction binop (reg-operand :cl) dst)]
:else [(mov-instruction src1 dst) (binary-instruction binop src2 dst)])))
(def tacky->assembly-transformers
diff --git a/src/cljcc/emit.clj b/src/cljcc/emit.clj
index d18edb3..2bce107 100644
--- a/src/cljcc/emit.clj
+++ b/src/cljcc/emit.clj
@@ -19,6 +19,8 @@
:dx "%edx"
:r10 "%r10d"
:r11 "%r11d"
+ :cx "%ecx"
+ :cl "%cl"
(throw (AssertionError. (str "Invalid register operand: " operand)))))
(def operand-emitters
@@ -104,8 +106,8 @@
instructions (map instruction-emit (:instructions f))]
(flatten [globl
name-line
- " pushq %rbp"
- " movq %rsp, %rbp"
+ " pushq %rbp"
+ " movq %rsp, %rbp"
instructions])))
(def emitters-top-level
@@ -122,8 +124,8 @@
(defn emit [ast]
(let [handle-os (fn [ast]
(if (= :linux (get-os))
- (conj (vec ast) linux-assembly-end)
- ast))]
+ (conj (conj (vec ast) linux-assembly-end) "\n")
+ (conj ast "\n")))]
(->> ast
(map emit-top-level)
concat
diff --git a/src/cljcc/tacky.clj b/src/cljcc/tacky.clj
index 5f09181..0c27271 100644
--- a/src/cljcc/tacky.clj
+++ b/src/cljcc/tacky.clj
@@ -39,11 +39,11 @@
:multiply :mul
:divide :div
:remainder :mod
- :bit-and :bit-and
- :bit-or :bit-or
- :bit-xor :bit-xor
- :bit-right-shift :bit-right-shift
- :bit-left-shift :bit-left-shift))
+ :ampersand :bit-and
+ :bitwise-or :bit-or
+ :bitwise-xor :bit-xor
+ :bitwise-right-shift :bit-right-shift
+ :bitwise-left-shift :bit-left-shift))
(defn- unary-instruction [unary-operator src dst]
{:type :unary
diff --git a/src/cljcc/token.clj b/src/cljcc/token.clj
index 429e593..9136631 100644
--- a/src/cljcc/token.clj
+++ b/src/cljcc/token.clj
@@ -11,18 +11,26 @@
:right-paren
;; operators
- :plus
- :minus
+ :bitwise-not
+
:multiply
:divide
:remainder
- :negate
- :assignemnt
+
+ :plus
+ :minus
+
+ :bitwise-left-shift
+ :bitwise-right-shift
+
:ampersand
- :bitwise-not
- :bitwise-or
+
:bitwise-xor
- :bitwise-left
+
+ :bitwise-or
+
+ :negate
+ :assignemnt
:increment
:decrement
@@ -39,11 +47,16 @@
(def bin-ops
"Binary operanrs and their precedence."
- {:plus 40
- :hyphen 40
- :multiply 50
- :divide 50
- :remainder 50})
+ {:multiply 100
+ :divide 100
+ :remainder 100
+ :plus 90
+ :hyphen 90
+ :bitwise-left-shift 80
+ :bitwise-right-shift 80
+ :ampersand 70
+ :bitwise-xor 60
+ :bitwise-or 50})
(def chrs-kind-map
{\( :left-paren
@@ -53,6 +66,11 @@
\= :assignment
"--" :decrement
"++" :increment
+ "<<" :bitwise-left-shift
+ ">>" :bitwise-right-shift
+ \^ :bitwise-xor
+ \| :bitwise-or
+ \& :ampersand
\; :semicolon
\+ :plus
\- :hyphen