This is the mail archive of the cgen@sources.redhat.com mailing list for the CGEN project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA:] In -build-operand!, -build-reg-operand, collect the natural mode, not the used mode,


Having thought about things a lot more, I think we should "remove"
the mode when computing the operands (for registers only, not sure
about memory).

So your patch it is!  With one alteration.

One reason why I was uncomfortable with removing the mode completely
is that while it may not have any effect on the generated code, per se,
mixed mode arithmetic is illegal.  To simplify writing description
files several shortcuts are allowed, but in general I think we want
to outlaw mode mismatches.

Therefore the result of -build-operand!,-build-reg-operand! still
has to have the requested mode.
So I propose this patch.  It records the natural mode of the operand
in the operand table, but if the requested mode is different, then
the operand's mode is explicitly converted before returning.

Ugh, I just realized that this patch doesn't handle floating point.
And I've left as a todo the checking of legal mode conversions.

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	20 Dec 2002 10:39:04 -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,32 @@
 	(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.
+      ; FIXME: error check, ensure smaller
+      (if (mode-compatible? 'samesize mode nub-mode)
+	  result-op
+	  (rtx-make 'trunc mode result-op))))
 )
 
 ; Subroutine of semantic-compile:process-expr!, to simplify it.
@@ -443,28 +458,40 @@
 
     (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.
+	    ; FIXME: error check, ensure smaller
+	    (if (mode-compatible? 'samesize mode nub-mode)
+		result-op
+		(rtx-make 'trunc mode result-op))))
 
 	(parse-error "FIXME" "unknown reg" expr)))
 )


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]