PROCEDURE Shift* (VAR x, y: DevCPL486.Item; subcl: BYTE); (* ASH, LSH, ROT *)
VAR L1, L2: DevCPL486.Label; c: DevCPL486.Item; opl, opr: INTEGER;
BEGIN
IF subcl = ash THEN opl := SHL; opr := SAR
ELSIF subcl = lsh THEN opl := SHL; opr := SHR
ELSE opl := ROL; opr := ROR
END;
IF y.mode = Con THEN
IF y.offset > 0 THEN
DevCPL486.GenShiftOp(opl, y, x)
ELSIF y.offset < 0 THEN
y.offset := -y.offset;
DevCPL486.GenShiftOp(opr, y, x)
END
ELSE
ASSERT(y.mode = Reg);
Check(y, -31, 31);
L1 := DevCPL486.NewLbl; L2 := DevCPL486.NewLbl;
DevCPL486.MakeConst(c, 0, y.form); DevCPL486.GenComp(c, y);
DevCPL486.GenJump(ccNS, L1, TRUE);
DevCPL486.GenNeg(y, FALSE);
DevCPL486.GenShiftOp(opr, y, x);
DevCPL486.GenJump(ccAlways, L2, TRUE);
DevCPL486.SetLabel(L1);
DevCPL486.GenShiftOp(opl, y, x);
DevCPL486.SetLabel(L2);
Free(y)
END;
IF x.mode # Reg THEN Free(x) END
END Shift;
ps SHL = SAL