diff options
| -rw-r--r-- | src/cljcc/compiler.clj | 6 | ||||
| -rw-r--r-- | src/cljcc/emit.clj | 10 | ||||
| -rw-r--r-- | src/cljcc/tacky.clj | 10 | ||||
| -rw-r--r-- | src/cljcc/token.clj | 42 |
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 |
