LoginSignup
3
1

More than 1 year has passed since last update.

Z80のHLレジスタの定数乗算を加算に展開するコンパイラ

Last updated at Posted at 2021-07-25

Z80のHLレジスタの定数乗算を加算命令に展開するコンパイラです。
2の補数を扱っているので、乗数や被乗数が負の数のときでも使えます。
但し、signed 16bitで表される、オーバーフローしない範囲での演算が正常です。
C言語で書かれています。
コンパイル cc z80constmul.c -o z80constmul
使用例 z80constmul <被乗数> <乗数>
2022/12/14 Ver2.0 バグがあったので、ソースを訂正しました。
2023/1/3 ver 2.1 ちょっと改良、最適化。

z80constmul.c
#include  <stdio.h>
#include  <stdlib.h>
// z80 compiler for expading constant multiplication of HL register to addition.
// Z80 HL*定数を加算命令に展開するコンパイラ Ver 2.1
// 乗数,被乗数は2の補数を扱っているので、負数も可
//
int main(int argc, char* argv[])
{
    short hl,de,l;
    int b=0;

    // 引数(乗数の取得)
    if (argc!=3) fprintf(stderr,"usage:z80constmul <被乗数> <乗数>\n"),exit(1);
    hl=(short) atoi(argv[1]);
    l=(short) atoi(argv[2]);

    // 乗数が何ビットあるか計算 (b=bit数となる)
    for(ushort r=(ushort)l;r;r>>=1 ) b++;

    // コンパイル(ヘッダ)
    if (l==0) printf("ld hl,0\n"),hl=0;
    else  {
      printf("ld hl,%d ; 被乗数 この行を省けばhlの値は何でもいい。\n",(int)hl);
      printf("ld d,h\n");
      printf("ld e,l\n");
      de=hl;

      // コンパイル(展開)
      for (int i=b-1;i>=0 ; i--) {
        if ( (((l>>i) & 1)!=0 ) && (i!=b-1))
          printf("add hl,de\n"),hl += de;
        if (i!=0)
          printf("add hl,hl\n"),hl += hl;
      }
    }

    printf(";hl=%d\n",(int) hl);
    exit(0);
}

実行例

$ z80constmul 100 0
ld hl,0
;hl=0
$ z80constmul 100 1
ld hl,100 ; 被乗数 この行を省けばhlの値は何でもいい。
ld d,h
ld e,l
;hl=100
$ z80constmul 100 20
ld hl,100 ; 被乗数 この行を省けばhlの値は何でもいい。
ld dprintf("ld de,hl\n");,h
ld e,l
add hl,hl
add hl,hl
add hl,de
add hl,hl
add hl,hl
;hl=2000
$ z80constmul 100 -1
ld hl,100 ; 被乗数 この行を省けばhlの値は何でもいい。
ld d,h
ld e,l
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
;hl=-100
$ z80constmul 100 -327
ld hl,100 ; 被乗数 この行を省けばhlの値は何でもいい。
ld d,h
ld e,l
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,hl
add hl,de
add hl,hl
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,hl
add hl,hl
add hl,de
;hl=-32700
$ z80constmul 0 3
ld hl,0 ; 被乗数 この行を省けばhlの値は何でもいい。
ld d,h
ld e,l
add hl,hl
add hl,de
;hl=0
$ z80constmul -3 -3
ld hl,-3 ; 被乗数 この行を省けばhlの値は何でもいい。
ld d,h
ld e,l
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,de
add hl,hl
add hl,hl
add hl,de
;hl=9

3
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1