fix 64-bit bitshifts on 32-bit systems

This commit is contained in:
Joel Dice 2008-01-10 13:47:55 -07:00
parent 15f627701b
commit 4c938d496e
2 changed files with 132 additions and 28 deletions

View File

@ -1331,6 +1331,12 @@ RegisterOperand::accept(Context* c, Operation op,
c->code.append(0xc0 | (value(c) << 3) | operand->value(c));
break;
case xor4:
rex(c);
c->code.append(0x31);
c->code.append(0xc0 | (operand->value(c) << 3) | value(c));
break;
default: abort(c);
}
}
@ -2065,18 +2071,37 @@ MemoryOperand::accept(Context* c, Operation op, RegisterOperand* operand)
case shl4:
case shl8: {
if (BytesPerWord == 4 and op == shl8) {
RegisterOperand* cx = temporary(c, rcx);
RegisterOperand* tmp = temporary(c);
RegisterOperand* count = temporary(c, rcx);
RegisterOperand* low = temporary(c);
RegisterOperand* high = temporary(c);
count->accept(c, mov, operand);
low->accept(c, mov, this);
high->accept(c, mov, this->high(c));
cx->accept(c, mov, operand);
tmp->accept(c, mov, this);
// shld
encode2(c, 0x0fa5, tmp->value(c), high(c), false);
// shl
encode(c, 0xd3, 4, this, false);
c->code.append(0x0f);
c->code.append(0xa5);
c->code.append(0xc0 | (high->value(c) << 3) | low->value(c));
tmp->release(c);
cx->release(c);
// shl
c->code.append(0xd3);
c->code.append(0xe0 | low->value(c));
count->accept(c, cmp, immediate(c, 32));
c->code.append(0x0f);
c->code.append(0x8c); // jl
c->code.append4(2 + 2);
high->accept(c, mov, low); // 2 bytes
low->accept(c, xor4, low); // 2 bytes
this->accept(c, mov, low);
this->high(c)->accept(c, mov, high);
high->release(c);
low->release(c);
count->release(c);
} else {
RegisterOperand* cx = temporary(c, rcx);
cx->accept(c, mov, operand);
@ -2088,18 +2113,40 @@ MemoryOperand::accept(Context* c, Operation op, RegisterOperand* operand)
case shr4:
case shr8: {
if (BytesPerWord == 4 and op == shr8) {
RegisterOperand* cx = temporary(c, rcx);
RegisterOperand* tmp = temporary(c);
RegisterOperand* count = temporary(c, rcx);
RegisterOperand* low = temporary(c);
RegisterOperand* high = temporary(c);
count->accept(c, mov, operand);
low->accept(c, mov, this);
high->accept(c, mov, this->high(c));
cx->accept(c, mov, operand);
tmp->accept(c, mov, high(c));
// shrd
encode2(c, 0x0fad, tmp->value(c), this, false);
// sar
encode(c, 0xd3, 7, high(c), false);
c->code.append(0x0f);
c->code.append(0xad);
c->code.append(0xc0 | (low->value(c) << 3) | high->value(c));
tmp->release(c);
cx->release(c);
// sar
c->code.append(0xd3);
c->code.append(0xf8 | high->value(c));
count->accept(c, cmp, immediate(c, 32));
c->code.append(0x0f);
c->code.append(0x8c); // jl
c->code.append4(2 + 3);
low->accept(c, mov, high); // 2 bytes
// sar 31,high
c->code.append(0xc1);
c->code.append(0xf8 | high->value(c));
c->code.append(31);
this->accept(c, mov, low);
this->high(c)->accept(c, mov, high);
high->release(c);
low->release(c);
count->release(c);
} else {
RegisterOperand* cx = temporary(c, rcx);
cx->accept(c, mov, operand);
@ -2111,18 +2158,37 @@ MemoryOperand::accept(Context* c, Operation op, RegisterOperand* operand)
case ushr4:
case ushr8: {
if (BytesPerWord == 4 and op == ushr8) {
RegisterOperand* cx = temporary(c, rcx);
RegisterOperand* tmp = temporary(c);
RegisterOperand* count = temporary(c, rcx);
RegisterOperand* low = temporary(c);
RegisterOperand* high = temporary(c);
cx->accept(c, mov, operand);
tmp->accept(c, mov, high(c));
// shrd
encode2(c, 0x0fad, tmp->value(c), this, false);
// shr
encode(c, 0xd3, 5, high(c), false);
count->accept(c, mov, operand);
low->accept(c, mov, this);
high->accept(c, mov, this->high(c));
tmp->release(c);
cx->release(c);
// shld
c->code.append(0x0f);
c->code.append(0xa5);
c->code.append(0xc0 | (low->value(c) << 3) | high->value(c));
// shl
c->code.append(0xd3);
c->code.append(0xe8 | high->value(c));
count->accept(c, cmp, immediate(c, 32));
c->code.append(0x0f);
c->code.append(0x8c); // jl
c->code.append4(2 + 2);
low->accept(c, mov, high); // 2 bytes
high->accept(c, xor4, high); // 2 bytes
this->accept(c, mov, low);
this->high(c)->accept(c, mov, high);
high->release(c);
low->release(c);
count->release(c);
} else {
RegisterOperand* cx = temporary(c, rcx);
cx->accept(c, mov, operand);

View File

@ -33,7 +33,45 @@ public class Misc {
}
}
public static void putInt(int val, byte[] dst, int offset) {
System.out.println("put " + val);
dst[offset] = (byte)((val >> 24) & 0xff);
dst[offset+1] = (byte)((val >> 16) & 0xff);
dst[offset+2] = (byte)((val >> 8) & 0xff);
dst[offset+3] = (byte)((val ) & 0xff);
}
public static void putLong(long val, byte[] dst, int offset) {
putInt((int)(val >> 32), dst, offset);
putInt((int)val, dst, offset + 4);
}
public static void main(String[] args) {
long x = 231;
expect((x >> 32) == 0);
expect((x >>> 32) == 0);
expect((x << 32) == 992137445376L);
long y = -231;
expect((y >> 32) == 0xffffffffffffffffL);
expect((y >>> 32) == 0xffffffffL);
byte[] array = new byte[8];
putLong(231, array, 0);
expect((array[0] & 0xff) == 0);
expect((array[1] & 0xff) == 0);
expect((array[2] & 0xff) == 0);
expect((array[3] & 0xff) == 0);
expect((array[4] & 0xff) == 0);
expect((array[5] & 0xff) == 0);
expect((array[6] & 0xff) == 0);
expect((array[7] & 0xff) == 231);
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(8);
buffer.putLong(231);
buffer.flip();
expect(buffer.getLong() == 231);
boolean v = Boolean.valueOf("true");
ClassLoader.getSystemClassLoader().toString();