• Bypassing Promotions

    From bill rowe@21:1/5 to All on Wed May 13 06:54:05 2020
    I maintain a compiler for the 8 bit 1802 family. https://sites.google.com/site/lcc1802/

    I built it mostly with assembly macros that line up with the internal operations. The code is readable(by me) and solid but tends to the clunky. One sore point with me is promotions. If I compare two unsigned chars the compiler feels obligated to
    promote both to ints and do a two byte compare so i end up with atrocities like:
    ; return a==b;
    ld1 R11,'O',sp,(3+1)
    zExt R11 ;CVUI2(INDIRU1(addr)): *widen unsigned char to signed int
    ld1 R10,'O',sp,(2+1)
    zExt R10 ;CVUI2(INDIRU1(addr)): *widen unsigned char to signed int
    jneU2 R11,R10,L3; NE

    I could recognize that pattern in the peephole optimizer but i could never be sure that intermediate results(R11 and R10) weren't being used further down.

    It would be better to go upstream into the generation rules to catch it. I can see the symbolic output for the same statement as below but i'm not clear on how i could catch part of it. Has anyone done it? Could it be as simple as NEI2(CVUI2(reg),CVUI2(
    reg))?
    ; return a==b;
    optimule.c:22.8:
    4. ADDRLP2 a
    3. INDIRU1 #4
    2. CVUI2 #3 1
    7. ADDRLP2 b
    6. INDIRU1 #7
    5. CVUI2 #6 1
    1' NEI2 #2 #5 3
    9. ADDRLP2 2
    10. CNSTI2 1
    8' ASGNI2 #9 #10 2 1
    12. ADDRGP2 4
    11' JUMPV #12
    3:
    15. ADDRLP2 2
    16. CNSTI2 0
    14' ASGNI2 #15 #16 2 1
    4:
    20. ADDRLP2 2
    19. INDIRI2 #20
    18' RETI2 #19

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From bill rowe@21:1/5 to All on Wed May 13 07:55:50 2020
    Update: That works quite well.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From jacobnavia@21:1/5 to All on Thu May 14 07:56:32 2020
    Le 13/05/2020 à 15:54, bill rowe a écrit :
    I maintain a compiler for the 8 bit 1802 family. https://sites.google.com/site/lcc1802/

    I built it mostly with assembly macros that line up with the internal operations. The code is readable(by me) and solid but tends to the clunky. One sore point with me is promotions. If I compare two unsigned chars the compiler feels obligated to
    promote both to ints and do a two byte compare so i end up with atrocities like:
    ; return a==b;
    ld1 R11,'O',sp,(3+1)
    zExt R11 ;CVUI2(INDIRU1(addr)): *widen unsigned char to signed int
    ld1 R10,'O',sp,(2+1)
    zExt R10 ;CVUI2(INDIRU1(addr)): *widen unsigned char to signed int
    jneU2 R11,R10,L3; NE

    I could recognize that pattern in the peephole optimizer but i could never be sure that intermediate results(R11 and R10) weren't being used further down.

    It would be better to go upstream into the generation rules to catch it. I can see the symbolic output for the same statement as below but i'm not clear on how i could catch part of it. Has anyone done it? Could it be as simple as NEI2(CVUI2(reg),
    CVUI2(reg))?
    ; return a==b;
    optimule.c:22.8:
    4. ADDRLP2 a
    3. INDIRU1 #4
    2. CVUI2 #3 1
    7. ADDRLP2 b
    6. INDIRU1 #7
    5. CVUI2 #6 1
    1' NEI2 #2 #5 3
    9. ADDRLP2 2
    10. CNSTI2 1
    8' ASGNI2 #9 #10 2 1
    12. ADDRGP2 4
    11' JUMPV #12
    3:
    15. ADDRLP2 2
    16. CNSTI2 0
    14' ASGNI2 #15 #16 2 1
    4:
    20. ADDRLP2 2
    19. INDIRI2 #20
    18' RETI2 #19



    I am using lcc 3.6, not lcc 4.2 but the underlying thing is the same. I
    had the same problem in the x86. I wanted to compare directly two chars
    instead of widening them to 32 bits and doing the comparison. I added
    following rule:

    stmt: NEI(CVCU(reg),CVCU(INDIRC(addr))) "\tcmpb\t%1,%0\
    \tjne\t%a\n"

    This way I compare directly without any widening.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)