R01 = 0x1234567; R02 = 2; R03 = 3; R00 = R02 + R03;
#include "osecpu_asm.h"
OSECPU_HEADER();
#define LMEMPP(reg, typ, preg) LMEM(reg, typ, preg); DB(0); PADDI(preg, typ, preg, 1)
#define SMEMPP(reg, typ, preg) SMEM(reg, typ, preg); DB(0); PADDI(preg, typ, preg, 1)
R04 = 0x100; R06 = 256; R07 = 256; PCALL(P1B); // open_window(256, 256);
R11 = 0; // y
LOOP(1, 0); // CONTINUEを使う回数, BREAKを使う回数.
R10 = 0; // x
LOOP(1, 0); // CONTINUEを使う回数, BREAKを使う回数.
R00 = R10 << 16;
R01 = R11 << 8;
R00 += R01; // 00xxyy00
SMEMPP(R00, T_UINT32, P04);
R10++;
CMPIJNE(R10, 256, CONTINUE);
ENDLOOP0(); // BREAKを使わない場合用、省略可能.
R11++;
CMPIJNE(R11, 256, CONTINUE);
ENDLOOP0(); // BREAKを使わない場合用、省略可能.
R04 = 0x101; R06 = 256; R07 = 256; R08 = 0; R09 = 0; PCALL(P1B); // flush(256, 256, 0, 0);
R04 = 0x102; R05 = 10000; PCALL(P1B); // sleep(10.000sec);int32s x == R00, y == R01; x += y;
include("osecpu_h.ask");
int32u *p:P10;
int32s x:R10, y:R11;
p = sys_openWin(256, 256);
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
*p++ = (x << 16) + (y << 8);
}
}
sys_flushWin(256, 256, 0, 0);
sys_sleep(10000); // 10.000secR10 = (R11 + R12 + R13); → ADD(R00,R11,R12);ADD(R10,R00,R13); R14 = 1 + 2 + 3; → LIMM(R14,0x6); R15 = 2 * R10 + 1; → MULI(R00,R10,0x2);ADDI(R15,R00,0x1);
NOT(a,b); → XOR(a,b,-1);
NEG(a,b); → SUB(a,0,b); or MUL(a,b,-1);
SHR(a,b,1); → SAR(a,b,1); AND(a,a,0x7fffffff);
SHR(a,b,c); → SAR(a,b,1); AND(a,a,0x7fffffff); SAR(a,a,c-1);
多倍長系の命令 → レジスタの下位16bitを演算に利用する、上位は桁あふれ検出用にする
それで任意のビット長を16bitで分割して演算していけば、64bitでも1024bitでも一応多倍長演算できる。
符号なしの大小比較 → 32bit符号なし整数の比較は、もしそのビットをフルに使って誤判断する可能性があるのであれば、
多倍長演算で48bit符号付き整数に拡張してやってください。 for (R11 = 0; R11 < 256; R11++) { // y
for (R10 = 0; R10 < 256; R10++) { // x
R00 = R10 << 16 | R11 << 8; // 00xxyy00
SMEMPP(R00, T_UINT32, P04);
}
}
osecpu027a>osecpu app0002.ose time: JITC=0.000[sec], exec=53.953[sec] size: OSECPU=106, native=74 osecpu028a>osecpu app0002.ose time: JITC=0.000[sec], exec=21.593[sec] size: OSECPU=106, native=67
| コメント | お名前 | NameLink | |