非専門的シンギュラリティー研究所

無限に動き続けるシステムを表す方法を AI なども使って考えていきます。

関数電卓コマンド版(2)

昔ながらの BASIC(9) - 非専門的シンギュラリティー研究所」で作った乗算と除算の関数 multiply2 と divide1 をコンパイルした結果を見てみます。

BITRANGE を以下のように定義します。

#define BITRANGE 16

乗算

int shift_multiply(int x, int y) {
    int c = 1 << BITRANGE;
    int result = 0;
    for (int i = 0; i < BITRANGE; i++) {
        y <<= 1;
        result <<= 1;
        if (y & c) {
            result += x;
        }
    }
    return result;
}

これをコンパイルすると以下のようになりました。

	move.l 8(%sp),%d1
	move.w #16,%a0
	moveq #0,%d0
.L3:
	add.l %d1,%d1
	add.l %d0,%d0
	btst #16,%d1
	jeq .L2
	add.l 4(%sp),%d0
.L2:
	subq.l #1,%a0
	cmp.w #0,%a0
	jne .L3
	rts

除算

int shift_divide(int x, int y) {
    int result = 0;
    y <<= BITRANGE;
    for (int i = 0; i < BITRANGE; i++) {
        y >>= 1;
        result <<= 1;
        if (x >= y) {
            result++;
            x -= y;
        }
    }
    return result;
}

これをコンパイルすると以下のようになりました。

	move.l 4(%sp),%a1
	move.l 8(%sp),%d1
	swap %d1
	clr.w %d1
	move.w #16,%a0
	moveq #0,%d0
.L10:
	asr.l #1,%d1
	add.l %d0,%d0
	cmp.l %d1,%a1
	jlt .L9
	addq.l #1,%d0
	sub.l %d1,%a1
.L9:
	subq.l #1,%a0
	cmp.w #0,%a0
	jne .L10
	rts