From 6aa5955f791771533d7ff8ac4f7f7d99b6f91641 Mon Sep 17 00:00:00 2001 From: Shagun Agrawal Date: Mon, 16 Dec 2024 22:24:44 +0530 Subject: Add tacky generation for signed, unsigned --- src/cljcc/analyze/typecheck.clj | 31 ++++++++----------------------- src/cljcc/schema.clj | 7 +++++++ src/cljcc/tacky.clj | 30 +++++++++++++++++++----------- src/cljcc/util.clj | 16 ++++++++++++++++ 4 files changed, 50 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/cljcc/analyze/typecheck.clj b/src/cljcc/analyze/typecheck.clj index 0c5d155..e042adc 100644 --- a/src/cljcc/analyze/typecheck.clj +++ b/src/cljcc/analyze/typecheck.clj @@ -7,7 +7,8 @@ [cljcc.symbol :as sym] [cljcc.analyze.resolve :as r] [cljcc.analyze.label-loops :as l] - [cljcc.exception :as exc])) + [cljcc.exception :as exc] + [cljcc.util :as u])) (declare typecheck-block typecheck-declaration to-static-init) @@ -54,31 +55,15 @@ :logical-not (set-type unary-exp {:type :int}) (set-type unary-exp (get-type typed-inner-e))))) -(defn- get-type-size [t] - (condp = t - {:type :int} 5 - {:type :uint} 5 - {:type :long} 10 - {:type :ulong} 10 - (exc/analyzer-error "Invalid type passed to get-type-size." {:type t}))) - -(defn type-signed? [t] - (condp = t - {:type :int} true - {:type :long} true - {:type :uint} false - {:type :ulong} false - (exc/analyzer-error "Invalid type passed to type-signed?." {:type t}))) - (defn- get-common-type [t1 t2] (cond (= t1 t2) t1 - (= (get-type-size t1) - (get-type-size t2)) (if (type-signed? t1) - t2 - t1) - (> (get-type-size t1) - (get-type-size t2)) t1 + (= (u/get-type-size t1) + (u/get-type-size t2)) (if (u/type-signed? t1) + t2 + t1) + (> (u/get-type-size t1) + (u/get-type-size t2)) t1 :else t2)) (defn- convert-to-exp diff --git a/src/cljcc/schema.clj b/src/cljcc/schema.clj index 6a4fb1f..46aa316 100644 --- a/src/cljcc/schema.clj +++ b/src/cljcc/schema.clj @@ -382,6 +382,12 @@ [:src #'TackyVal] [:dst #'TackyVal]]) +(def TackyZeroExtend + [:map + [:type [:= :zero-extend]] + [:src #'TackyVal] + [:dst #'TackyVal]]) + (def TackyUnary [:map [:type [:= :unary]] @@ -437,6 +443,7 @@ [:return #'TackyReturn] [:sign-extend #'TackySignExtend] [:truncate #'TackyTruncate] + [:zero-extend #'TackyZeroExtend] [:unary #'TackyUnary] [:binary #'TackyBinary] [:copy #'TackyCopy] diff --git a/src/cljcc/tacky.clj b/src/cljcc/tacky.clj index 678c74e..b88411e 100644 --- a/src/cljcc/tacky.clj +++ b/src/cljcc/tacky.clj @@ -5,6 +5,7 @@ [cljcc.parser :as p] [cljcc.exception :as exc] [cljcc.symbol :as sym] + [malli.core :as m] [malli.dev.pretty :as pretty] [cljcc.analyze.typecheck :as tc] [cljcc.analyze.core :as a] @@ -118,6 +119,11 @@ :src src :dst dst}) +(defn- zero-extend-instruction [src dst] + {:type :zero-extend + :src src + :dst dst}) + (defn- copy-instruction [src dst] {:type :copy :src src @@ -187,15 +193,18 @@ value (let [dst (variable "cast_") _ (add-var-to-symbol dst target-type symbols) + inner-type (tc/get-type typed-inner) {res :val - insts :instructions} value] - (if (= :long (:type target-type)) - {:val dst - :instructions (flatten [insts - (sign-extend-instruction res dst)])} - {:val dst - :instructions (flatten [insts - (truncate-instruction res dst)])})))) + insts :instructions} value + cast-i (cond + (= (u/get-type-size target-type) + (u/get-type-size inner-type)) (copy-instruction res dst) + (< (u/get-type-size target-type) + (u/get-type-size inner-type)) (truncate-instruction res dst) + (u/type-signed? inner-type) (sign-extend-instruction res dst) + :else (zero-extend-instruction res dst))] + {:val dst + :instructions (flatten [insts cast-i])}))) (defmethod exp-handler :unary-exp [exp symbols] @@ -517,9 +526,8 @@ symbols (atom ident->symbol) function-instructions (tacky-function-instructions ast symbols) program (vec (concat variable-instructions function-instructions)) - ;_ (m/coerce s/TackyProgram program) - ;_ (m/coerce s/SymbolMap @symbols) - ] + _ (m/coerce s/TackyProgram program) + _ (m/coerce s/SymbolMap @symbols)] {:program program :ident->symbol @symbols})) diff --git a/src/cljcc/util.clj b/src/cljcc/util.clj index eb77ad6..c9fc208 100644 --- a/src/cljcc/util.clj +++ b/src/cljcc/util.clj @@ -110,3 +110,19 @@ [v] (and (>= v Integer/MIN_VALUE) (<= v Integer/MAX_VALUE))) + +(defn get-type-size [t] + (condp = t + {:type :int} 5 + {:type :uint} 5 + {:type :long} 10 + {:type :ulong} 10 + (exc/analyzer-error "Invalid type passed to get-type-size." {:type t}))) + +(defn type-signed? [t] + (condp = t + {:type :int} true + {:type :long} true + {:type :uint} false + {:type :ulong} false + (exc/analyzer-error "Invalid type passed to type-signed?." {:type t}))) -- cgit v1.2.3