tkchia / gcc-ia16

Fork of Lambertsen & Jenner (& al.)'s IA-16 (Intel 16-bit x86) port of GNU compilers ― added far pointers & more • use https://github.com/tkchia/build-ia16 to build • Ubuntu binaries at https://launchpad.net/%7Etkchia/+archive/ubuntu/build-ia16/ • DJGPP/MS-DOS binaries at https://gitlab.com/tkchia/build-ia16/-/releases • mirror of https://gitlab.com/tkchia/gcc-ia16
GNU General Public License v2.0
174 stars 13 forks source link

Inefficient long shift without rcl instruction. #34

Closed bartoldeman closed 5 years ago

bartoldeman commented 6 years ago
unsigned long shl1(unsigned long x)
{
  return x << 1;
}

gives rise to code like this:

       cmpb    $0x80,  %ah
        sbbw    %cx,    %cx
        incw    %cx
        shlw    $1,     %dx
        orw     %cx,    %dx
        shlw    $1,     %ax

where I was expecting this

        shlw    $1,     %ax
        rclw    $1,     %dx

using return x + x; gives code you'd expect using add and adc.

tkchia commented 6 years ago

Hello @bartoldeman ,

Thanks! Yes --- the internal machine description currently has special patterns for multi-word addition and subtraction, but none for multi-word left or right shifts by 1. I will see if I can add such a pattern into gcc-ia16.

tkchia commented 5 years ago

Hello @bartoldeman ,

I have added support for using rclw for multi-word left shifts by small constant amounts, so that

unsigned long shl_ul3 (unsigned long x)
{
  return x << 3;
}

unsigned long long shl_ull1 (unsigned long long x)
{
  return x << 1;
}

under -Os -mregparmcall now yields

    .arch i8086,jumps
    .code16
    .att_syntax prefix
#NO_APP
    .text
    .global shl_ul3
    .type   shl_ul3, @function
shl_ul3:
    shlw    %ax
    rclw    %dx
    shlw    %ax
    rclw    %dx
    shlw    %ax
    rclw    %dx
    ret
    .size   shl_ul3, .-shl_ul3
    .global shl_ull1
    .type   shl_ull1, @function
shl_ull1:
    pushw   %si
    pushw   %di
    pushw   %bp
    movw    %sp,    %bp
    movw    8(%bp), %bx
    movw    10(%bp),    %cx
    movw    12(%bp),    %dx
    movw    14(%bp),    %si
    shlw    %bx
    rclw    %cx
    rclw    %dx
    rclw    %si
    movw    %ax,    %di
    movw    %bx,    (%di)
    movw    %cx,    2(%di)
    movw    %dx,    4(%di)
    movw    %si,    6(%di)
    popw    %bp
    popw    %di
    popw    %si
    ret $8
    .size   shl_ull1, .-shl_ull1
    .ident  "GCC: (GNU) 6.3.0"

I hope to also implement constant right shifts using rcrw in the near future (this is a bit trickier).

Thank you!

tkchia commented 5 years ago

Argh! I committed a patch to add rcrw for constant right shifts, but it ended up segfaulting GCC while it was building libgcc, so now I am undoing the patch while I try to figure out what is wrong.

Thank you!