-static void genrshFour (operand *result, operand *left,
- int shCount, int sign)
-{
- /* if shifting more that 3 bytes */
- if(shCount >= 24 ) {
- shCount -= 24;
- if(shCount)
- shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
- else
- movLeft2Result(left, MSB32, result, LSB, sign);
- addSign(result, MSB16, sign);
- }
- else if(shCount >= 16){
- shCount -= 16;
- if(shCount)
- shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
- else{
- movLeft2Result(left, MSB24, result, LSB, 0);
- movLeft2Result(left, MSB32, result, MSB16, sign);
- }
- addSign(result, MSB24, sign);
- }
- else if(shCount >= 8){
- shCount -= 8;
- if(shCount == 1)
- shiftRLong(left, MSB16, result, sign);
- else if(shCount == 0){
- movLeft2Result(left, MSB16, result, LSB, 0);
- movLeft2Result(left, MSB24, result, MSB16, 0);
- movLeft2Result(left, MSB32, result, MSB24, sign);
- addSign(result, MSB32, sign);
- }
- else{
- shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
- shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
- /* the last shift is signed */
- shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
- addSign(result, MSB32, sign);
- }
- }
- else{ /* 1 <= shCount <= 7 */
- if(shCount <= 2){
- shiftRLong(left, LSB, result, sign);
- if(shCount == 2)
- shiftRLong(result, LSB, result, sign);
- }
- else{
- shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
- shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
- shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
- }
+static void
+genrshFour (operand * result, operand * left,
+ int shCount, int sign)
+{
+ /* if shifting more that 3 bytes */
+ if (shCount >= 24)
+ {
+ shCount -= 24;
+ if (shCount)
+ shiftR1Left2Result (left, MSB32, result, LSB, shCount, sign);
+ else
+ movLeft2Result (left, MSB32, result, LSB, sign);
+ addSign (result, MSB16, sign);
+ }
+ else if (shCount >= 16)
+ {
+ shCount -= 16;
+ if (shCount)
+ shiftR2Left2Result (left, MSB24, result, LSB, shCount, sign);
+ else
+ {
+ movLeft2Result (left, MSB24, result, LSB, 0);
+ movLeft2Result (left, MSB32, result, MSB16, sign);
+ }
+ addSign (result, MSB24, sign);
+ }
+ else if (shCount >= 8)
+ {
+ shCount -= 8;
+ if (shCount == 1)
+ shiftRLong (left, MSB16, result, sign);
+ else if (shCount == 0)
+ {
+ movLeft2Result (left, MSB16, result, LSB, 0);
+ movLeft2Result (left, MSB24, result, MSB16, 0);
+ movLeft2Result (left, MSB32, result, MSB24, sign);
+ addSign (result, MSB32, sign);
+ }
+ else
+ {
+ shiftR2Left2Result (left, MSB16, result, LSB, shCount, 0);
+ shiftLLeftOrResult (left, MSB32, result, MSB16, 8 - shCount);
+ /* the last shift is signed */
+ shiftR1Left2Result (left, MSB32, result, MSB24, shCount, sign);
+ addSign (result, MSB32, sign);
+ }
+ }
+ else
+ { /* 1 <= shCount <= 7 */
+ if (shCount <= 2)
+ {
+ shiftRLong (left, LSB, result, sign);
+ if (shCount == 2)
+ shiftRLong (result, LSB, result, sign);
+ }
+ else
+ {
+ shiftR2Left2Result (left, LSB, result, LSB, shCount, 0);
+ shiftLLeftOrResult (left, MSB24, result, MSB16, 8 - shCount);
+ shiftR2Left2Result (left, MSB24, result, MSB24, shCount, sign);
+ }
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genRightShiftLiteral - right shifting by known count */
+/*-----------------------------------------------------------------*/
+static void
+genRightShiftLiteral (operand * left,
+ operand * right,
+ operand * result,
+ iCode * ic,
+ int sign)
+{
+ int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ int size;
+
+ freeAsmop (right, NULL, ic, TRUE);
+
+ aopOp (left, ic, FALSE);
+ aopOp (result, ic, FALSE);
+
+#if VIEW_SIZE
+ emitcode ("; shift right ", "result %d, left %d", AOP_SIZE (result),
+ AOP_SIZE (left));
+#endif
+
+ size = getDataSize (left);
+ /* test the LEFT size !!! */
+
+ /* I suppose that the left size >= result size */
+ if (shCount == 0)
+ {
+ size = getDataSize (result);
+ while (size--)
+ movLeft2Result (left, size, result, size, 0);
+ }
+
+ else if (shCount >= (size * 8))
+ {
+ if (sign)
+ /* get sign in acc.7 */
+ MOVA (aopGet (AOP (left), size - 1, FALSE, FALSE));
+ addSign (result, LSB, sign);
+ }
+ else
+ {
+ switch (size)
+ {
+ case 1:
+ genrshOne (result, left, shCount, sign);
+ break;
+
+ case 2:
+ genrshTwo (result, left, shCount, sign);
+ break;
+
+ case 4:
+ genrshFour (result, left, shCount, sign);
+ break;
+ default:
+ break;
+ }
+
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genSignedRightShift - right shift of signed number */
+/*-----------------------------------------------------------------*/
+static void
+genSignedRightShift (iCode * ic)
+{
+ operand *right, *left, *result;
+ int size, offset;
+ char *l;
+ symbol *tlbl, *tlbl1;
+
+ /* we do it the hard way put the shift count in b
+ and loop thru preserving the sign */
+
+ right = IC_RIGHT (ic);
+ left = IC_LEFT (ic);
+ result = IC_RESULT (ic);
+
+ aopOp (right, ic, FALSE);
+
+
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ genRightShiftLiteral (left, right, result, ic, 1);
+ return;
+ }
+ /* shift count is unknown then we have to form
+ a loop get the loop count in B : Note: we take
+ only the lower order byte since shifting
+ more that 32 bits make no sense anyway, ( the
+ largest size of an object can be only 32 bits ) */
+
+ emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
+ emitcode ("inc", "b");
+ freeAsmop (right, NULL, ic, TRUE);
+ aopOp (left, ic, FALSE);
+ aopOp (result, ic, FALSE);
+
+ /* now move the left to the result if they are not the
+ same */
+ if (!sameRegs (AOP (left), AOP (result)) &&
+ AOP_SIZE (result) > 1)
+ {
+
+ size = AOP_SIZE (result);
+ offset = 0;
+ while (size--)
+ {
+ l = aopGet (AOP (left), offset, FALSE, TRUE);
+ if (*l == '@' && IS_AOP_PREG (result))
+ {
+
+ emitcode ("mov", "a,%s", l);
+ aopPut (AOP (result), "a", offset);
+ }
+ else
+ aopPut (AOP (result), l, offset);
+ offset++;
+ }
+ }
+
+ /* mov the highest order bit to OVR */
+ tlbl = newiTempLabel (NULL);
+ tlbl1 = newiTempLabel (NULL);
+
+ size = AOP_SIZE (result);
+ offset = size - 1;
+ emitcode ("mov", "a,%s", aopGet (AOP (left), offset, FALSE, FALSE));
+ emitcode ("rlc", "a");
+ emitcode ("mov", "ov,c");
+ /* if it is only one byte then */
+ if (size == 1)
+ {
+ l = aopGet (AOP (left), 0, FALSE, FALSE);
+ MOVA (l);
+ emitcode ("sjmp", "%05d$", tlbl1->key + 100);
+ emitcode ("", "%05d$:", tlbl->key + 100);
+ emitcode ("mov", "c,ov");
+ emitcode ("rrc", "a");
+ emitcode ("", "%05d$:", tlbl1->key + 100);
+ emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+ aopPut (AOP (result), "a", 0);
+ goto release;
+ }
+
+ reAdjustPreg (AOP (result));
+ emitcode ("sjmp", "%05d$", tlbl1->key + 100);
+ emitcode ("", "%05d$:", tlbl->key + 100);
+ emitcode ("mov", "c,ov");
+ while (size--)
+ {
+ l = aopGet (AOP (result), offset, FALSE, FALSE);
+ MOVA (l);
+ emitcode ("rrc", "a");
+ aopPut (AOP (result), "a", offset--);