4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Last updated at Posted at 2021-07-25

Z80のHLレジスタの定数乗算を加算命令に展開するコンパイラです。
2の補数を扱っているので、乗数や被乗数が負の数のときでも使えます。
但し、signed 16bitで表される、オーバーフローしない範囲での演算が正常です。

C版 コンパイル cc z80constmul.c -o z80constmul

使用例 z80constmul <被乗数> <乗数>

2022/12 Ver2.0 バグがあったので、ソースを訂正しました。
2023/1 ver 2.1 ちょっと改良、最適化。

2024/8/30 ver 2.1 python version

C バージョン

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);
}

python バージョン

z80constmul.py
#!/usr/bin/python3
import sys
#
# Z80 HL*定数を加算命令に展開するコンパイラ Ver 2.1
# 2の補数を扱っているので、被乗数、乗数共に負数も可
# 

# 何ビットあるか計算 (b=bit数となる)
def nbit(l):
    b=0
    r=l
    while(r):
        r>>=1
        b+=1
    return b

# 2の補数表示
def print2complement(i):
    print(f"{i if i<0x8000 else i-65536}",end="")

# expand
def expand(hl,l):
    hl=hl&0xffff
    l=l&0xffff
    b=nbit(l)

    # ヘッダ
    if l==0:
        print("ld hl,0")
        hl=0
        return hl

    print("ld hl,",end='')
    print2complement(hl)
    print("; 被乗数 この行を省けばhlの値は何でもいい。");
    print("ld d,h");
    print("ld e,l");
    de=hl;

    # 展開
    for i in range(b-1,-1,-1):
        if l>>i & 1 and i!=b-1:
            print("add hl,de")
            hl = (hl+de)&0xffff
        if i:
            print("add hl,hl")
            hl = (hl+hl)&0xffff
    return hl

# main
def main(hl,l):
    hl=expand(hl,l)
    print(f";hl=",end="")
    print2complement(hl)
    print("")
    return

if __name__=="__main__":
    if len(sys.argv)!=3:
        print("Usage:z80constmul.py <被乗数> <乗数>")
        exit(1)
    main(int(sys.argv[1]),int(sys.argv[2]))
    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

4
1
2

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
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?