🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Andreas Luik Tue, 22 Dec 1992 19:47
truncation SImode -> HImode wrong if word_mode == QImode
#1417
Author: Andreas Luik
Date: Tue, 22 Dec 1992 19:47
98 lines
3398 bytes
Program:	gcc
Version:	2.3.2

Host:		sparc-sun-sunos4.1.3
Target:		own
Area:		cc1

Input file: 	trunc.c

static void discardl (long l)	{}
void trunc ()
{
    long l;
    long long ll = (long long) 0x300040005;
    l = ll;     discardl (l);
}

gcc command:	gcc -S trunc.c

Synopsis:	truncation SImode -> HImode wrong if word_mode == QImode

Description:

    Assume a 16-bit word addressable target machine. Then the machine
    modes are:
    
	BITS_PER_UNIT			16
	BITS_PER_WORD			16
	UNITS_PER_WORD			1
    
	QImode = 16 Bits (C-Types char, short & int)
	HImode = 32 Bits (C-Type long)
	SImode = 64 Bits (C-Type long long)
	word_mode = QImode
    
    The assignment "(long) l = (long long) ll" must truncate the 64-Bit SImode
    value to the 32-Bit HImode value. This should be done by
    convert_move() [expr.c]. to_mode is HImode, from_mode is SImode. 
    
    convert_move() does nothing until it reaches the following statements: 
    
      if (GET_MODE_BITSIZE (from_mode) > BITS_PER_WORD)
	{
	  convert_move (to, gen_lowpart (word_mode, from), 0);
	  return;
	}
    
    As the condition is true, convert_mode() is recursively called with a
    source rtx with mode word_mode, i.e. QImode! This is wrong of course.

    (Usually this works because the conditions are as follows: from_mode
    must be DImode (> BITS_PER_WORD), to_mode must be != from_mode
    (otherwise convert_move will simply call emit_move_insn()), i.e.
    SImode. From (DImode) will be converted to lowpart(SImode, from) which
    will then work because to has a mode <= SImode. Note that this will
    fail in traditional architectures if integer arithmetic on TImode
    (16 byte ints) will be supported.)
    
    I don't understand the purpose of the above condition. The code that
    follows in convert_move() will handle all cases. Especially the code
    that handles from_mode DImode using CODE_FOR_truncdixx2 following the
    above condition will never get executed.
    
    Would you please check whether this condition (which should serve any
    optimization purpose I suppose) should not be eliminated.

Reproduce with:

    Difficult without appropriate target description. Please check the
    code. Maybe you may add a "truncdisi2" insn to a 32-bit target description
    (e.g. sparc.md) and see it ignored (if TRULY_NOOP_TRUNCATION is 0).

Fix:

*** expr.c.ORIG	Thu Dec  3 02:10:13 1992
--- expr.c	Thu Dec 17 18:55:10 1992
***************
*** 704,714 ****
--- 704,716 ----
        return;
      }
  
+ #if 0
    if (GET_MODE_BITSIZE (from_mode) > BITS_PER_WORD)
      {
        convert_move (to, gen_lowpart (word_mode, from), 0);
        return;
      }
+ #endif
  
    /* Handle pointer conversion */			/* SPEE 900220 */
    if (to_mode == PSImode)



-- 
Andreas Luik                E-Mail: luik@isa.de
(postmaster@isa.de)         UUCP:   ...!{uunet!unido,pyramid}!isaak!luik
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads