mirror of
https://github.com/golang/go
synced 2024-11-26 14:46:47 -07:00
64bit literal RSH
R=rsc APPROVED=rsc DELTA=85 (35 added, 0 deleted, 50 changed) OCL=33761 CL=33767
This commit is contained in:
parent
9a36b8087c
commit
c6fd23ce6d
@ -17,7 +17,7 @@ cgen64(Node *n, Node *res)
|
|||||||
Node al, ah, bl, bh, cl, ch; //, s1, s2;
|
Node al, ah, bl, bh, cl, ch; //, s1, s2;
|
||||||
Prog *p1;
|
Prog *p1;
|
||||||
//, *p2;
|
//, *p2;
|
||||||
// uint64 v;
|
uint64 v;
|
||||||
// uint32 lv, hv;
|
// uint32 lv, hv;
|
||||||
|
|
||||||
if(res->op != OINDREG && res->op != ONAME) {
|
if(res->op != OINDREG && res->op != ONAME) {
|
||||||
@ -191,54 +191,83 @@ cgen64(Node *n, Node *res)
|
|||||||
// regfree(&s2);
|
// regfree(&s2);
|
||||||
// break;
|
// break;
|
||||||
|
|
||||||
// case ORSH:
|
case ORSH:
|
||||||
// if(r->op == OLITERAL) {
|
if(r->op == OLITERAL) {
|
||||||
// fatal("cgen64 ORSH, OLITERAL not implemented");
|
v = mpgetfix(r->val.u.xval);
|
||||||
// v = mpgetfix(r->val.u.xval);
|
if(v >= 64) {
|
||||||
// if(v >= 64) {
|
if(hi1.type->etype == TINT32) {
|
||||||
// if(is64(r->type))
|
// MOVW hi1->31, al
|
||||||
// splitclean();
|
p1 = gins(AMOVW, &hi1, &al);
|
||||||
// splitclean();
|
p1->from.type = D_SHIFT;
|
||||||
// split64(res, &lo2, &hi2);
|
p1->from.offset = SHIFT_AR | 31 << 7 | hi1.val.u.reg;
|
||||||
// if(hi1.type->etype == TINT32) {
|
p1->from.reg = NREG;
|
||||||
// gmove(&hi1, &lo2);
|
|
||||||
// gins(ASARL, ncon(31), &lo2);
|
|
||||||
// gmove(&hi1, &hi2);
|
|
||||||
// gins(ASARL, ncon(31), &hi2);
|
|
||||||
// } else {
|
|
||||||
// gins(AMOVL, ncon(0), &lo2);
|
|
||||||
// gins(AMOVL, ncon(0), &hi2);
|
|
||||||
// }
|
|
||||||
// splitclean();
|
|
||||||
// goto out;
|
|
||||||
// }
|
|
||||||
// if(v >= 32) {
|
|
||||||
// if(is64(r->type))
|
|
||||||
// splitclean();
|
|
||||||
// split64(res, &lo2, &hi2);
|
|
||||||
// gmove(&hi1, &lo2);
|
|
||||||
// if(v > 32)
|
|
||||||
// gins(optoas(ORSH, hi1.type), ncon(v-32), &lo2);
|
|
||||||
// if(hi1.type->etype == TINT32) {
|
|
||||||
// gmove(&hi1, &hi2);
|
|
||||||
// gins(ASARL, ncon(31), &hi2);
|
|
||||||
// } else
|
|
||||||
// gins(AMOVL, ncon(0), &hi2);
|
|
||||||
// splitclean();
|
|
||||||
// splitclean();
|
|
||||||
// goto out;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // general shift
|
// MOVW hi1->31, ah
|
||||||
// gins(AMOVL, &lo1, &ax);
|
p1 = gins(AMOVW, &hi1, &ah);
|
||||||
// gins(AMOVL, &hi1, &dx);
|
p1->from.type = D_SHIFT;
|
||||||
// p1 = gins(ASHRL, ncon(v), &ax);
|
p1->from.offset = SHIFT_AR | 31 << 7 | hi1.val.u.reg;
|
||||||
// p1->from.index = D_DX; // double-width shift
|
p1->from.reg = NREG;
|
||||||
// p1->from.scale = 0;
|
} else {
|
||||||
// gins(optoas(ORSH, hi1.type), ncon(v), &dx);
|
gins(AEOR, &al, &al);
|
||||||
// break;
|
gins(AEOR, &ah, &ah);
|
||||||
// }
|
}
|
||||||
// fatal("cgen64 ORSH, !OLITERAL not implemented");
|
break;
|
||||||
|
}
|
||||||
|
if(v >= 32) {
|
||||||
|
if(hi1.type->etype == TINT32) {
|
||||||
|
// MOVW hi1->(v-32), al
|
||||||
|
p1 = gins(AMOVW, &hi1, &al);
|
||||||
|
p1->from.type = D_SHIFT;
|
||||||
|
p1->from.offset = SHIFT_AR | (v-32)<<7 | hi1.val.u.reg;
|
||||||
|
p1->from.reg = NREG;
|
||||||
|
|
||||||
|
// MOVW hi1->31, ah
|
||||||
|
p1 = gins(AMOVW, &hi1, &ah);
|
||||||
|
p1->from.type = D_SHIFT;
|
||||||
|
p1->from.offset = SHIFT_AR | 31<<7 | hi1.val.u.reg;
|
||||||
|
p1->from.reg = NREG;
|
||||||
|
} else {
|
||||||
|
// MOVW hi1>>(v-32), al
|
||||||
|
p1 = gins(AMOVW, &hi1, &al);
|
||||||
|
p1->from.type = D_SHIFT;
|
||||||
|
p1->from.offset = SHIFT_LR | (v-32)<<7 | hi1.val.u.reg;
|
||||||
|
p1->from.reg = NREG;
|
||||||
|
gins(AEOR, &ah, &ah);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// general shift
|
||||||
|
|
||||||
|
// MOVW lo1>>v, al
|
||||||
|
p1 = gins(AMOVW, &lo1, &al);
|
||||||
|
p1->from.type = D_SHIFT;
|
||||||
|
p1->from.offset = SHIFT_LR | v<<7 | lo1.val.u.reg;
|
||||||
|
p1->from.reg = NREG;
|
||||||
|
|
||||||
|
// OR hi1<<(32-v), al, al
|
||||||
|
p1 = gins(AORR, &hi1, &al);
|
||||||
|
p1->from.type = D_SHIFT;
|
||||||
|
p1->from.offset = SHIFT_LL | (32-v)<<7 | hi1.val.u.reg;
|
||||||
|
p1->from.reg = NREG;
|
||||||
|
p1->reg = al.val.u.reg;
|
||||||
|
|
||||||
|
if(hi1.type->etype == TINT32) {
|
||||||
|
// MOVW hi1->v, ah
|
||||||
|
p1 = gins(AMOVW, &hi1, &ah);
|
||||||
|
p1->from.type = D_SHIFT;
|
||||||
|
p1->from.offset = SHIFT_AR | v<<7 | hi1.val.u.reg;
|
||||||
|
p1->from.reg = NREG;
|
||||||
|
} else {
|
||||||
|
// MOVW hi1>>v, ah
|
||||||
|
p1 = gins(AMOVW, &hi1, &ah);
|
||||||
|
p1->from.type = D_SHIFT;
|
||||||
|
p1->from.offset = SHIFT_LR | v<<7 | hi1.val.u.reg;
|
||||||
|
p1->from.reg = NREG;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fatal("cgen64 ORSH, !OLITERAL not implemented");
|
||||||
|
|
||||||
// // load value into DX:AX.
|
// // load value into DX:AX.
|
||||||
// gins(AMOVL, &lo1, &ax);
|
// gins(AMOVL, &lo1, &ax);
|
||||||
|
@ -811,7 +811,7 @@ rdst:
|
|||||||
|
|
||||||
hard:
|
hard:
|
||||||
// requires register intermediate
|
// requires register intermediate
|
||||||
regalloc(&r1, cvt, T);
|
regalloc(&r1, cvt, N);
|
||||||
gmove(f, &r1);
|
gmove(f, &r1);
|
||||||
gmove(&r1, t);
|
gmove(&r1, t);
|
||||||
regfree(&r1);
|
regfree(&r1);
|
||||||
|
@ -203,6 +203,12 @@ enum as
|
|||||||
#define C_SCOND_NONE 14
|
#define C_SCOND_NONE 14
|
||||||
#define C_SCOND_NV 15
|
#define C_SCOND_NV 15
|
||||||
|
|
||||||
|
/* D_SHIFT type */
|
||||||
|
#define SHIFT_LL 0<<5
|
||||||
|
#define SHIFT_LR 1<<5
|
||||||
|
#define SHIFT_AR 2<<5
|
||||||
|
#define SHIFT_RR 3<<5
|
||||||
|
|
||||||
/* type/name */
|
/* type/name */
|
||||||
#define D_GOK 0
|
#define D_GOK 0
|
||||||
#define D_NONE 1
|
#define D_NONE 1
|
||||||
|
Loading…
Reference in New Issue
Block a user