From: user5857@newsgrouper.org.invalid   
      
   EricP posted:   
      
   > MitchAlsup wrote:   
   > > My 66000 2.0   
   > >   
   > > After 4-odd years of ISA stability, I ran into a case where   
   > > I needed to change the instruction formats.   
   > > And after bragging to Quadribloc about its stability--it   
   > > reached the point where it was time to switch to version 2.0.   
   > >   
   > > Well, its time to eat crow.   
   > > --------------------------------------------------------------   
   > > Memory reference instructions already produce 64-bit values   
   > > from Byte, HalfWord, Word and DoubleWord memory references   
   > > in both Signed and unSigned flavors. These supports both   
   > > integer and floating point due to the single register file.   
   > >   
   > > Essentially, I need that property in both integer and floating   
   > > point calculations to eliminate instructions that merely apply   
   > > value range constraints--just like memory !   
   >   
   > Why? Compilers do not have any problem with this   
   > as its been handled by overload resolution since forever.   
      
   LLVM compiles C with stricter typing than GCC resulting in a lot   
   of smashes:: For example::   
      
   int subroutine( int a, int b )   
   {   
    return a+b;   
   }   
      
   Compiles into:   
      
   subroutine:   
    ADD R1,R1,R2   
    SRA R1,R1,<32,0> // limit result to (int)   
    RET   
      
   LLVM thinks the smash is required because [-2^31..+2^31-1] +   
   [-2^31..+2^31-1] does not always fit into [-2^31..+2^31-1] !!!   
   and chasing down all the cases is harder than the compiler is   
   ready to do. At first I though that the Value propagation in   
   LLVM would find that the vast majority of arithmetic does not   
   need smashing. This proved frustrating to both myself and to   
   Brian. The more I read RSIC-V and ARM assembly code, the more   
   I realized that adding sized integer arithmetic is the only   
   way to get through to the LLVM infrastructure.   
      
   We (the My 66000 team; mostly me and Brian) have been trying to   
   obey the stricter than necessary typing of LLVM and achieve the   
   code density possible as if K&R rules were in play with 64-bit   
   only (int)s.   
      
   RISC-V has ADDW (but no ADDH or ADDB) to alleviate the issue on   
   a majority of calculations. ARM has word sized Registers to   
   alleviate the issue. Since ARM started as 32-bits ADDW is natural.   
   I am exploring how to provide integer arithmetic such that smashing   
   never has to happen.   
      
   We have been chasing smashes for 9 months making little progress...   
      
   > Its people who have the problems following type changes and most   
   > compilers will warn of mixed type operations for exactly that reason.   
      
   It is more the ADA problem that values must fit in containers--that   
   is values have a range {min..max} and that calculated values outside   
   of that range are to be "addressed".   
      
   > > ISA 2.0 changes allows calculation instructions; both Integer   
   > > and Floating Point; and a few other miscellaneous instructions   
   > > (not so easily classified) the same uniformity.   
   > >   
   > > In all cases, an integer calculation produces a 64-bit value   
   > > range limited to that of the {Sign}×{Size}--no garbage bits   
   > > in the high parts of the registers--the register accurately   
   > > represents the calculation as specified {Sign}×{Size}.   
   > >   
   > > Integer and floating point compare instructions only compare   
   > > bits of the specified {Size}.   
   > >   
   > > Conversions between integer and floating point are now also   
   > > governed by {Size} so one can directly convert FP64 directly   
   > > into {unSigned}×{Int16}--more fully supporting strongly typed   
   > > languages.   
   >   
   > Strongly typed languages don't natively support mixed type operations.   
   > They come with a set of predefined operations for specific types that   
   > produce specific results.   
      
   Yes, indeed, and this is what I am providing: {Sign}×{Size} calculations.   
   Where the result is known to be range lmited to {Sign}×{Size}. Thus:   
      
    ADDSH R7,R8,R9   
      
   R7 is range limited {Signed}×{HalfWord} == [-32768..+32767]   
   ------------------------------------------------------------------------   
   So let's look at some egregious cases::   
      
    cvtds r2,r2 // convert double to signed 64   
    srl r3,r2,#0,#32 // convert signed 64 to signed 32   
   --------   
    sra r1,r23,#0,#32 // smash to signed 32   
    sra r2,r20,#0,#32 // smash to signed 32   
    maxs r23,r2,r1 // max of signed 32   
   --------   
    ldd r24,[r24] // LD signed 64   
    add r1,r28,#1 // innocently add #1   
    sra r28,r1,#0,#32 // smash to Signed 32   
    cmp r1,r28,r16 // to match the other operand of CMP   
   --------   
    call strspn   
    srl r2,r1,#0,#32 // smash result Signed 32   
    add r1,r25,-r1   
    sra r1,r1,#0,#32 // smash Signed 32   
    cmp r2,r19,r2   
    srl r2,r2,#2,#1   
    add r21,r21,r2 // add Bool to Signed 32   
    sra r2,r20,#0,#32 // smash Signed 32   
    maxs r20,r1,r2 // MAX Signed 32   
   --------   
    mov r1,r29 // Signed 64   
    ple0 r17,FFFFFFF // ignore   
    stw r17,[ip,key_rows] // ignore   
    add r1,r29,#-1 // innocent subtract   
    sra r1,r1,#0,#32 // smash to Signed 32   
    divs r1,r1,r17 // DIV Signed 32   
   --------   
    lduw r2,[ip,keyT+4]   
    add r2,r2,#-1 // innocent subtract   
    srl r2,r2,#0,#32 // smash to unSigned 32   
    cmp r3,r2,#1 // CMP unSigned 32   
    // even though CMP is Signless   
   --------   
    add r1,r19,-r6 // not so innocent subtract   
    sra r2,r1,#0,#32 // Signed   
    srl r1,r1,#0,#32 // unSigned   
    // only one of these can be eliminated   
   --------   
      
   > If YOU want operators/functions that allow mixed types then they force   
   > you to define your own functions to perform your specific operations,   
   > and it forces you to deal with the consequences of your type mixing.   
   >   
   > All this does is force YOU, the programmer, to be explicit in your   
   > definition and not depend on invisible compiler specific interpretations.   
   >   
   > If you want to support Uns8 * Int8 then it forces you, the programmer,   
   > to deal with the fact that this produces a signed 16-bit result   
   > in the range -128*256..+127*256 = -32768..32512.   
      
   Uns8 occupies 64-bits in a register range-limited to [0..255]   
   Int8 occupies 64-bits in a register range-limited to [-128..127]   
   So, integer values sitting in registers occupy the whole 64-bits   
   but are properly range-limited to base-type.   
      
   Multiply multiplies 2×64-bit registers and produces a 128-bit   
   result, since CARRY is not in effect, the bits<127..64> are   
   discarded; bits<63..0> are then considered.   
      
   unSigned results simply discard bits more significant than base-type.   
   Signed results raise OVERFLOW is there is more significance than   
   base-type (and if enabled take an exception).   
   In all cases, the result delivered fits within the range of base-type.   
      
   So, in the case you mention::   
      
    LDUB R8,[---]   
    LDSB R9,[---]   
    MULSH R7,R8,R9 // result range [-32768..32767]   
   -----   
    MULUH R7,R8,R9 // result range [0..65535]   
      
      
   > Now if you want to convert that result bit pattern to Uns8 by truncating   
      
   [continued in next message]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|