This is the mail archive of the
cgen@sources.redhat.com
mailing list for the CGEN project.
Re: [RFA:] In -build-operand!, -build-reg-operand, collect the natural mode, not the used mode,
- From: Doug Evans <dje at transmeta dot com>
- To: Hans-Peter Nilsson <hans-peter dot nilsson at axis dot com>
- Cc: cgen at sources dot redhat dot com
- Date: Mon, 13 Jan 2003 22:08:51 -0800
- Subject: Re: [RFA:] In -build-operand!, -build-reg-operand, collect the natural mode, not the used mode,
- References: <15866.32849.125398.731160@casey.transmeta.com><200212140138.gBE1c6HA026946@ignucius.axis.se>
When we last left our story, I had proposed this patch and then
pointed out that it didn't handle floating point or sets.
I'm not sure how to handle floating point other than to defer
a decision on how to handle it and flag an error if the size
changes for now. So that's what this patch does now.
w.r.t. sets: there's various solutions but I think this patch
can still go in.
I propose checking this in.
2003-01-13 Doug Evans <dje@sebabeach.org>
* semantics.scm (-build-operand!): Record operand in its natural mode.
(-build-reg-operand!): Ditto.
Index: semantics.scm
===================================================================
RCS file: /cvs/src/src/cgen/semantics.scm,v
retrieving revision 1.2
diff -u -p -r1.2 semantics.scm
--- semantics.scm 20 Dec 2002 06:39:04 -0000 1.2
+++ semantics.scm 14 Jan 2003 06:03:55 -0000
@@ -407,8 +407,14 @@
(let* ((mode (mode-real-name (if (eq? mode 'DFLT)
(op:mode op)
mode)))
+ ; NUB-MODE is the mode to use to uniquify all the operands.
+ ; For registers it is the natural mode of the register.
+ ; For memory it is the mode of the use/set.
+ (nub-mode (if (register? (op:type op))
+ (op:mode op)
+ mode))
; The first #f is a placeholder for the object.
- (try (list '-op- #f mode op-name #f))
+ (try (list '-op- #f nub-mode op-name #f))
(existing-op (-rtx-find-op try op-list)))
(if (and (pc? op)
@@ -416,23 +422,37 @@
(append! sem-attrs
(list (if (tstate-cond? tstate) 'COND-CTI 'UNCOND-CTI))))
- ; If already present, return the object, otherwise add it.
- (if existing-op
-
- (cadr existing-op)
-
- ; We can't set the operand number yet 'cus we don't know it.
- ; However, when it's computed we'll need to set all associated
- ; operands. This is done by creating shared rtx (a la gcc) - the
- ; operand number then need only be updated in one place.
-
- (let ((xop (op:new-mode op mode)))
- (op:set-cond?! xop (tstate-cond? tstate))
- ; Set the object rtx in `try', now that we have it.
- (set-car! (cdr try) (rtx-make 'xop xop))
- ; Add the operand to in/out-ops.
- (append! op-list (list try))
- (cadr try))))
+ (let ((result-op
+ ; If already recorded, use it, otherwise add it.
+ (if existing-op
+
+ (cadr existing-op)
+
+ ; We can't set the operand number yet 'cus we don't know it.
+ ; However, when it's computed we'll need to set all associated
+ ; operands. This is done by creating shared rtx (a la gcc) -
+ ; the operand number then need only be updated in one place.
+
+ (let ((xop (op:new-mode op nub-mode)))
+ (op:set-cond?! xop (tstate-cond? tstate))
+ ; Set the object rtx in `try', now that we have it.
+ (set-car! (cdr try) (rtx-make 'xop xop))
+ ; Add the operand to in/out-ops.
+ (append! op-list (list try))
+ (cadr try)))))
+
+ ; We can't return a mode different than requested. Mixing
+ ; modes in things like and,add,etc. is illegal.
+ ; If MODE isn't the nub mode, wrap the operand in a mode change.
+ ; Not sure how to handle floats so just punt for now and flag an
+ ; error if the size changes.
+ (if (mode-compatible? 'samesize mode nub-mode)
+ result-op
+ (if (mode-float? (mode:lookup mode))
+ (error "floating point operand implicitly referenced in different mode")
+ (if (mode-bigger? nub-mode mode)
+ (rtx-make 'trunc mode result-op)
+ (error "implicit reference of operand in bigger mode"))))))
)
; Subroutine of semantic-compile:process-expr!, to simplify it.
@@ -443,28 +463,45 @@
(if hw
; If the mode is DFLT, use the object's natural mode.
- (let* ((mode (mode-real-name (if (eq? (rtx-mode expr) 'DFLT)
- (obj:name (hw-mode hw))
+ (let* (; Always record the register in the operand table using its
+ ; natural mode.
+ (nub-mode (obj:name (hw-mode hw)))
+ (mode (mode-real-name (if (eq? (rtx-mode expr) 'DFLT)
+ nub-mode
(rtx-mode expr))))
(indx-sel (rtx-reg-index-sel expr))
; #f is a place-holder for the object (filled in later)
- (try (list 'reg #f mode hw-name indx-sel))
+ (try (list 'reg #f nub-mode hw-name indx-sel))
(existing-op (-rtx-find-op try op-list)))
- ; If already present, return the object, otherwise add it.
- (if existing-op
-
- (cadr existing-op)
-
- (let ((xop (apply reg (cons (tstate->estate tstate)
- (cons mode
- (cons hw-name indx-sel))))))
- (op:set-cond?! xop (tstate-cond? tstate))
- ; Set the object rtx in `try', now that we have it.
- (set-car! (cdr try) (rtx-make 'xop xop))
- ; Add the operand to in/out-ops.
- (append! op-list (list try))
- (cadr try))))
+ (let ((result-op
+ ; If already recorded, use it, otherwise add it.
+ (if existing-op
+
+ (cadr existing-op)
+
+ (let ((xop (apply reg (cons (tstate->estate tstate)
+ (cons nub-mode
+ (cons hw-name indx-sel))))))
+ (op:set-cond?! xop (tstate-cond? tstate))
+ ; Set the object rtx in `try', now that we have it.
+ (set-car! (cdr try) (rtx-make 'xop xop))
+ ; Add the operand to in/out-ops.
+ (append! op-list (list try))
+ (cadr try)))))
+
+ ; We can't return a mode different than requested. Mixing
+ ; modes in things like and,add,etc. is illegal.
+ ; If MODE isn't the nub mode, wrap the operand in a mode change.
+ ; Not sure how to handle floats so just punt for now and flag an
+ ; error if the size changes.
+ (if (mode-compatible? 'samesize mode nub-mode)
+ result-op
+ (if (mode-float? (mode:lookup mode))
+ (error "floating point operand implicitly referenced in different mode")
+ (if (mode-bigger? nub-mode mode)
+ (rtx-make 'trunc mode result-op)
+ (error "implicit reference of operand in bigger mode"))))))
(parse-error "FIXME" "unknown reg" expr)))
)