|
|
Power 6/32 Unix version 1.2b
#define error_hdl2 error
#define error_hdl3 error
#define C 0x1
#define V 0x2
#define Z 0x4
#define N 0x8
extern long scoplp;
extern long force_lp;
/* MUL instruction */
/* some global variables used in ASM */
static long flag_msk, psl, product, mult, muld, mulp, add, prod1, prod2;
static long exp_reslt1, exp_reslt2;
mul()
{
asm("movl $2,_no_opr"); /* number of operands in use */
mull2(); /* Test MULL2 instruction */
mull3(); /* Test MULL3 instruction */
exmul(); /* Test EMUL instruction */
asm("jmp *return");
}
static mull2()
{ long exp_psw , ix;
/* multiply long with 2 operands */
for(ix=0;ix<2;ix++)
{
setjmp();
asm("m1: movab m1,_stpc");
flag_msk = exp_psw = C;
flag_msk = N|Z|V|C;
if (ix==0) {
mult = 0xabcde;
mulp = 0xaba; }
else {
mulp = 0xabcde;
mult = 0xaba; }
mull(2,0x732de54c,exp_psw);
}
for(ix=0;ix<2;ix++)
{
asm("m2: movab m2,_stpc");
flag_msk = exp_psw = C;
flag_msk = N|Z|V|C;
if (ix==0) {
mult = -200;
mulp = -1000; }
else {
mulp = -200;
mult = -1000; }
mull(2,200000,exp_psw);
}
for(ix=0;ix<2;ix++)
{
asm("m3: movab m3,_stpc");
flag_msk = exp_psw = 0;
flag_msk = Z|V|C; /* set all flags except N */
exp_psw = N | C;
if (ix==0) {
mult = 1234;
mulp = -500; }
else {
mulp = 1234;
mult = -500; }
mull(2,-617000,exp_psw);
}
for(ix=0;ix<2;ix++)
{
asm("m4: movab m4,_stpc");
flag_msk = exp_psw = 0;
flag_msk = N|V|C; /* set all flags except Z */
exp_psw = Z | C;
if (ix==0) {
mult = 0x1234;
mulp = 0; }
else {
mulp = 0x1234;
mult = 0; }
mull(2,0,exp_psw);
}
/* test V bit, Overflow */
for(ix=0;ix<2;ix++)
{
asm("m5: movab m5,_stpc");
flag_msk = exp_psw = 0;
exp_psw = (V); /* any other flags may be set */
if (ix==0) {
mult = 0x80000000; /* Max negative no. */
mulp = -1; }
else {
mulp = 0x80000000;
mult = -1; }
mull(2,0,exp_psw);
}
for(ix=0;ix<2;ix++)
{
asm("m6: movab m6,_stpc");
flag_msk = exp_psw = 0;
exp_psw = (V); /* any other flags may be set */
if (ix==0) {
mult = -65646;
mulp = 65646; }
else {
mulp = -65646;
mult = 65646; }
mull(2,0,exp_psw);
}
}
static mull3()
{ long exp_psw , ix;
/* multiply long with 3 operands */
for(ix=0;ix<2;ix++)
{
asm("m7: movab m7,_stpc");
flag_msk = exp_psw = C;
flag_msk = N|Z|V|C;
if (ix==0) {
mult = 0x12345;
mulp = 0xbff; }
else {
mulp = 0x12345;
mult = 0xbff; }
mull(3,0xda618bb,exp_psw);
}
for(ix=0;ix<2;ix++)
{
asm("m8: movab m8,_stpc");
flag_msk = exp_psw = C;
flag_msk = N|Z|V|C;
if (ix==0) {
mult = -3001;
mulp = -300; }
else {
mulp = -3001;
mult = -300; }
mull(3,900300,exp_psw);
}
for(ix=0;ix<2;ix++)
{
asm("m9: movab m9,_stpc");
flag_msk = exp_psw = 0;
flag_msk = Z|V|C; /* set all flags except N */
exp_psw = N | C;
if (ix==0) {
mult = 1234;
mulp = -500; }
else {
mulp = 1234;
mult = -500; }
mull(3,-617000,exp_psw);
}
for(ix=0;ix<2;ix++)
{
asm("m10: movab m10,_stpc");
flag_msk = exp_psw = 0;
flag_msk = N|V; /* set all flags except Z,C */
exp_psw = Z | C;
if (ix==0) {
mult = 0x1234;
mulp = 0; }
else {
mulp = 0x1234;
mult = 0; }
mull(3,0,exp_psw);
}
/* test V bit */
for(ix=0;ix<2;ix++)
{
asm("m11: movab m11,_stpc");
flag_msk = exp_psw = 0;
exp_psw = (V); /* any other flags may be set */
if (ix==0) {
mult = 0x80000000; /* Max negative no. */
mulp = -1; }
else {
mulp = 0x80000000; /* Max negative no. */
mult = -1; }
mull(3,0,exp_psw);
}
for(ix=0;ix<2;ix++)
{
asm("m12: movab m12,_stpc");
flag_msk = exp_psw = 0;
exp_psw = (V); /* any other flags may be set */
if (ix==0) {
mult = -65646;
mulp = 65646; }
else {
mulp = -65646;
mult = 65646; }
mull(3,0,exp_psw);
}
}
static exmul()
{ long exp_psw ;
/* extended multiply */
asm("m13: movab m13,_stpc");
flag_msk = exp_psw = 0;
flag_msk = N|V|C; /* set N,V,C flags */
exp_psw = Z | C;
exp_reslt1 = 0;
exp_reslt2 = 0;
/* mult = -4; */
asm("movl $-4,_mult"); /* so not to use mnegl */
muld = 5;
add = 20;
emul(exp_psw);
asm("m14: movab m14,_stpc");
flag_msk = exp_psw = 0;
flag_msk = Z|V|C; /* set Z,V,C flags */
exp_psw = N | C;
asm("movl $0xffffffff,_exp_reslt1");
asm("movl $0xffffffff,_exp_reslt2");
/* exp_reslt1 = 0xffffffff;
exp_reslt2 = 0xffffffff; */
/* Expected result is a quad : 0xffffffffffffffff (-1) */
mult = -4000;
muld = 50;
add = 199999;
emul(exp_psw);
asm("m15: movab m15,_stpc");
flag_msk = exp_psw = C;
flag_msk = N|Z|V|C; /* set all flags */
exp_reslt2 = 0x60000000 ;
exp_reslt1 = 0x01000000 ;
/* Expected result is a quad : 0x0100000060000000 */
mult = 0xfffffff;
muld = 0xfffffff;
add = 0x7fffffff;
emul(exp_psw);
}
/* ROUTINE TO EXECUTE MULL2 AND MULL3 */
static mull(type,exp_result,exp_psw)
long exp_result, exp_psw, type;
{
long op1, op2, psw, ix;
char *msg1, *msg2;
flag_msk = flag_msk << 16;
op1 = mult;
op2 = mulp;
for(;;)
{
for (ix=0;ix<8;ix++)
{
mult = op1;
mulp = op2;
/* set flags */
if (type == 2) {
if (ix==0) { /* Memory to memory */
setjmp();
asm("movl $1,_subtst");
asm("bicpsw $0xf");
asm("bispsw _flag_msk"); /* set flags */
asm("mull2 _mult,_mulp");
asm("movpsl _psl"); /* save PSL */
product = mulp;
}
if (ix==1) { /* Register to register */
setjmp();
asm("movl $2,_subtst");
asm("movl _mult,r3");
asm("movl _mulp,r4");
asm("bicpsw $0xf");
asm("bispsw _flag_msk"); /* set flags */
asm("mull2 r3,r4");
asm("movpsl _psl"); /* save PSL */
asm("movl r4,_mulp");
product = mulp;
}
if (ix==2) { /* Memory to register */
setjmp();
asm("movl $3,_subtst");
asm("movl _mulp,r4");
asm("bicpsw $0xf");
asm("bispsw _flag_msk"); /* set flags */
asm("mull2 _mult,r4");
asm("movpsl _psl"); /* save PSL */
asm("movl r4,_mulp");
product = mulp;
}
if (ix==3) { /* Register to memory */
setjmp();
asm("movl $4,_subtst");
asm("movl _mult,r3");
asm("bicpsw $0xf");
asm("bispsw _flag_msk"); /* set flags */
asm("mull2 r3,_mulp");
asm("movpsl _psl"); /* save PSL */
product = mulp;
}
}
else {
if (ix==0) { /* Memory to memory to memory */
setjmp();
asm("movl $5,_subtst");
asm("bicpsw $0xf");
asm("bispsw _flag_msk"); /* set flags */
asm("mull3 _mult,_mulp,_product");
asm("movpsl _psl"); /* save PSL */
}
if (ix==1) { /* Register to register to register */
setjmp();
asm("movl $6,_subtst");
asm("movl _mult,r3");
asm("movl _mulp,r4");
asm("bicpsw $0xf");
asm("bispsw _flag_msk"); /* set flags */
asm("mull3 r3,r4,r6");
asm("movpsl _psl"); /* save PSL */
asm("movl r6,_product");
}
if (ix==2) { /* Memory to register to memory */
setjmp();
asm("movl $7,_subtst");
asm("movl _mulp,r4");
asm("bicpsw $0xf");
asm("bispsw _flag_msk"); /* set flags */
asm("mull3 _mult,r4,_product");
asm("movpsl _psl"); /* save PSL */
}
if (ix==3) { /* Register to memory to register */
setjmp();
asm("movl $8,_subtst");
asm("movl _mult,r3");
asm("bicpsw $0xf");
asm("bispsw _flag_msk"); /* set flags */
asm("mull3 r3,_mulp,r6");
asm("movpsl _psl"); /* save PSL */
asm("movl r6,_product");
}
if (ix==4) { /* Register to register to memory */
setjmp();
asm("movl $9,_subtst");
asm("movl _mult,r3");
asm("movl _mulp,r4");
asm("bicpsw $0xf");
asm("bispsw _flag_msk"); /* set flags */
asm("mull3 r3,r4,_product");
asm("movpsl _psl"); /* save PSL */
}
if (ix==5) { /* Memory to register to register */
setjmp();
asm("movl $0xa,_subtst");
asm("movl _mulp,r4");
asm("bicpsw $0xf");
asm("bispsw _flag_msk"); /* set flags */
asm("mull3 _mult,r4,r6");
asm("movpsl _psl"); /* save PSL */
asm("movl r6,_product");
}
if (ix==6) { /* Register to memory to memory */
setjmp();
asm("movl $0xb,_subtst");
asm("movl _mult,r3");
asm("bicpsw $0xf");
asm("bispsw _flag_msk"); /* set flags */
asm("mull3 r3,_mulp,_product");
asm("movpsl _psl"); /* save PSL */
}
if (ix==7) { /* Memory to memory to register */
setjmp();
asm("movl $0xc,_subtst");
asm("bicpsw $0xf");
asm("bispsw _flag_msk"); /* set flags */
asm("mull3 _mult,_mulp,r6");
asm("movpsl _psl"); /* save PSL */
asm("movl r6,_product");
}
}
psw = psl & 0xf; /* mask out high order word of PSL */
/* check flags */
if (exp_psw & V){ /* On expected overflows */
if( !(psw & V) ) { /* We only look at the (V) flag */
asm("movl $2,_ercode");
if (scoplp) longjmp();
error_hdl2(psw,exp_psw,op1,op2);
}
continue; /* skip other checks */
}
else if (psw != exp_psw)
{
asm("movl $2,_ercode");
if (scoplp) longjmp();
error_hdl2(psw,exp_psw,op1,op2);
}
if (mult != op1)
{
asm("movl $3,_ercode");
if (scoplp) longjmp();
error_hdl2(mult,op1,op1,op2);
}
if (type == 3)
{
if (mulp != op2)
{
asm("movl $3,_ercode");
if (scoplp) longjmp();
error_hdl2(mulp,op2,op1,op2);
}
}
if (product != exp_result)
{ /* error in multiply operation */
asm("movl $1,_ercode");
if (scoplp) longjmp();
error_hdl2(product,exp_result,op1,op2);
}
if (force_lp) longjmp();
}
break;
}
}
/* ROUTINE TO EXECUTE EMUL */
static emul(exp_psw)
long exp_psw;
{
long op1, op2, op3, psw, type;
char *msg1, *msg2;
flag_msk = flag_msk << 16;
op1 = mult;
op2 = muld;
op3 = add;
for(;;)
{
msg1 = "** Test EMUL **\n";
for(type=0;type<8;type++)
{
mult = op1;
muld = op2;
add = op3;
if (type==0) { /* Memory memory memory memory */
asm("movl $0xd,_subtst");
asm("bicpsw $0xf"); /* clear all flags */
asm("bispsw _flag_msk"); /* set flags */
asm("emul _mult,_muld,_add,_prod1");
asm("movpsl _psl"); /* save PSL */
psw = psl & 0xf;
}
if (type==1) { /* Register,register,register register */
asm("movl $0xe,_subtst");
asm("movl _mult,r3");
asm("movl _muld,r4");
asm("movl _add,r5");
asm("bicpsw $0xf"); /* clear all flags */
asm("bispsw _flag_msk"); /* set flags */
asm("emul r3,r4,r5,r6");
asm("movpsl _psl"); /* save PSL */
psw = psl & 0xf;
asm("movl r6,_prod1");
asm("movl r7,_prod2");
}
if (type==2) { /* Register register Memory memory */
asm("movl $0xf,_subtst");
asm("movl _mult,r3");
asm("movl _muld,r4");
asm("bicpsw $0xf"); /* clear all flags */
asm("bispsw _flag_msk"); /* set flags */
asm("emul r3,r4,_add,_prod1");
asm("movpsl _psl"); /* save PSL */
psw = psl & 0xf;
}
if (type==3) { /* Register memory Memory register */
asm("movl $0x10,_subtst");
asm("movl _mult,r3");
asm("bicpsw $0xf"); /* clear all flags */
asm("bispsw _flag_msk"); /* set flags */
asm("emul r3,_muld,_add,r6");
asm("movpsl _psl"); /* save PSL */
psw = psl & 0xf;
asm("movl r6,_prod1");
asm("movl r7,_prod2");
}
if (type==4) { /* Memory memory register memory */
asm("movl $0x11,_subtst");
asm("movl _add,r5");
asm("bicpsw $0xf"); /* clear all flags */
asm("bispsw _flag_msk"); /* set flags */
asm("emul _mult,_muld,r5,_prod1");
asm("movpsl _psl"); /* save PSL */
psw = psl & 0xf;
}
if (type==5) { /* Register memory register memory */
asm("movl $0x12,_subtst");
asm("movl _mult,r3");
asm("movl _add,r5");
asm("bicpsw $0xf"); /* clear all flags */
asm("bispsw _flag_msk"); /* set flags */
asm("emul r3,_muld,r5,_prod1");
asm("movpsl _psl"); /* save PSL */
psw = psl & 0xf;
}
if (type==6) { /* Memory register register memory */
asm("movl $0x13,_subtst");
asm("movl _muld,r4");
asm("movl _add,r5");
asm("bicpsw $0xf"); /* clear all flags */
asm("bispsw _flag_msk"); /* set flags */
asm("emul _mult,r4,r5,_prod1");
asm("movpsl _psl"); /* save PSL */
psw = psl & 0xf;
}
if (type==7) { /* Memory register memory register */
asm("movl $0x14,_subtst");
asm("movl _muld,r4");
asm("bicpsw $0xf"); /* clear all flags */
asm("bispsw _flag_msk"); /* set flags */
asm("emul _mult,r4,_add,r6");
asm("movpsl _psl"); /* save PSL */
psw = psl & 0xf;
asm("movl r6,_prod1");
asm("movl r7,_prod2");
}
if ( prod1 != exp_reslt1)
{ /* error in ext. multiply operation */
asm("movl $1,_ercode");
if (scoplp) longjmp();
error(prod1,exp_reslt1,op1,op2);
}
if ( prod2 != exp_reslt2 )
{ /* error in ext. multiply operation */
asm("movl $1,_ercode");
if (scoplp) longjmp();
error(prod2,exp_reslt2,op1,op2);
}
/* check flags */
if (psw!=exp_psw)
{
asm("movl $3,_no_opr");
asm("movl $2,_ercode");
if (scoplp) longjmp();
error_hdl3(psw,exp_psw,op1,op2,op3);
}
if (mult != op1)
{
asm("movl $3,_no_opr");
asm("movl $3,_ercode");
if (scoplp) longjmp();
error_hdl3(mult,op1,op1,op2,op3);
}
if (muld != op2)
{
asm("movl $3,_no_opr");
asm("movl $3,_ercode");
if (scoplp) longjmp();
error_hdl3(muld,op2,op1,op2,op3);
}
if (add != op3)
{
asm("movl $3,_no_opr");
asm("movl $3,_ercode");
if (scoplp) longjmp();
error_hdl3(add,op3,op1,op2,op3);
}
if (force_lp) longjmp();
}
break;
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.