mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
Merge branch 'master' into wip
This commit is contained in:
commit
34f51114a1
100
classpath/avian/Utf8.java
Normal file
100
classpath/avian/Utf8.java
Normal file
@ -0,0 +1,100 @@
|
||||
/* Copyright (c) 2010, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package avian;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class Utf8 {
|
||||
public static boolean test(Object data) {
|
||||
if (!(data instanceof byte[])) return false;
|
||||
byte[] b = (byte[])data;
|
||||
for (int i = 0; i < b.length; ++i) {
|
||||
if (((int)b[i] & 0x080) != 0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static byte[] encode(char[] s16, int offset, int length) {
|
||||
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||
for (int i = offset; i < offset+length; ++i) {
|
||||
char c = s16[i];
|
||||
if (c == '\u0000') { // null char
|
||||
buf.write(0);
|
||||
buf.write(0);
|
||||
} else if (c < 0x080) { // 1 byte char
|
||||
buf.write(c);
|
||||
} else if (c < 0x0800) { // 2 byte char
|
||||
buf.write(0x0c0 | (c >>> 6));
|
||||
buf.write(0x080 | (c & 0x03f));
|
||||
} else { // 3 byte char
|
||||
buf.write(0x0e0 | ((c >>> 12) & 0x0f));
|
||||
buf.write(0x080 | ((c >>> 6) & 0x03f));
|
||||
buf.write(0x080 | (c & 0x03f));
|
||||
}
|
||||
}
|
||||
return buf.toByteArray();
|
||||
}
|
||||
|
||||
public static Object decode(byte[] s8, int offset, int length) {
|
||||
Object buf = new byte[length];
|
||||
boolean isMultiByte = false;
|
||||
int i=offset, j=0;
|
||||
while (i < offset+length) {
|
||||
int x = s8[i++];
|
||||
if ((x & 0x080) == 0x0) { // 1 byte char
|
||||
if (x == 0) ++i; // 2 byte null char
|
||||
cram(buf, j++, x);
|
||||
} else if ((x & 0x0e0) == 0x0c0) { // 2 byte char
|
||||
if (!isMultiByte) {
|
||||
buf = widen(buf, j, length-1);
|
||||
isMultiByte = true;
|
||||
}
|
||||
int y = s8[i++];
|
||||
cram(buf, j++, ((x & 0x1f) << 6) | (y & 0x3f));
|
||||
} else if ((x & 0x0f0) == 0x0e0) { // 3 byte char
|
||||
if (!isMultiByte) {
|
||||
buf = widen(buf, j, length-2);
|
||||
isMultiByte = true;
|
||||
}
|
||||
int y = s8[i++]; int z = s8[i++];
|
||||
cram(buf, j++, ((x & 0xf) << 12) | ((y & 0x3f) << 6) | (z & 0x3f));
|
||||
}
|
||||
}
|
||||
|
||||
return trim(buf, j);
|
||||
}
|
||||
|
||||
public static char[] decode16(byte[] s8, int offset, int length) {
|
||||
Object decoded = decode(s8, offset, length);
|
||||
if (decoded instanceof char[]) return (char[])decoded;
|
||||
return (char[])widen(decoded, length, length);
|
||||
}
|
||||
|
||||
private static void cram(Object data, int index, int val) {
|
||||
if (data instanceof byte[]) ((byte[])data)[index] = (byte)val;
|
||||
else ((char[])data)[index] = (char)val;
|
||||
}
|
||||
|
||||
private static Object widen(Object data, int length, int capacity) {
|
||||
byte[] src = (byte[])data;
|
||||
char[] result = new char[capacity];
|
||||
for (int i = 0; i < length; ++i) result[i] = (char)((int)src[i] & 0x0ff);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Object trim(Object data, int length) {
|
||||
if (data instanceof byte[]) return data;
|
||||
if (((char[])data).length == length) return data;
|
||||
char[] result = new char[length];
|
||||
System.arraycopy(data, 0, result, 0, length);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -10,6 +10,8 @@
|
||||
|
||||
package java.io;
|
||||
|
||||
import avian.Utf8;
|
||||
|
||||
public class InputStreamReader extends Reader {
|
||||
private final InputStream in;
|
||||
|
||||
@ -31,10 +33,16 @@ public class InputStreamReader extends Reader {
|
||||
public int read(char[] b, int offset, int length) throws IOException {
|
||||
byte[] buffer = new byte[length];
|
||||
int c = in.read(buffer);
|
||||
for (int i = 0; i < c; ++i) {
|
||||
b[i + offset] = (char) buffer[i];
|
||||
|
||||
if (c <= 0) return c;
|
||||
|
||||
char[] buffer16 = Utf8.decode16(buffer, 0, c);
|
||||
|
||||
for (int i = 0; i < buffer16.length; ++i) {
|
||||
b[i + offset] = buffer16[i];
|
||||
}
|
||||
return c;
|
||||
|
||||
return buffer16.length;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
package java.io;
|
||||
|
||||
import avian.Utf8;
|
||||
|
||||
public class OutputStreamWriter extends Writer {
|
||||
private final OutputStream out;
|
||||
|
||||
@ -18,11 +20,7 @@ public class OutputStreamWriter extends Writer {
|
||||
}
|
||||
|
||||
public void write(char[] b, int offset, int length) throws IOException {
|
||||
byte[] buffer = new byte[length];
|
||||
for (int i = 0; i < length; ++i) {
|
||||
buffer[i] = (byte) b[i + offset];
|
||||
}
|
||||
out.write(buffer);
|
||||
out.write(Utf8.encode(b, offset, length));
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
|
@ -15,8 +15,8 @@ import java.util.regex.Pattern;
|
||||
import java.util.Comparator;
|
||||
import java.util.Formatter;
|
||||
import java.util.Locale;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Serializable;
|
||||
import avian.Utf8;
|
||||
|
||||
public final class String
|
||||
implements Comparable<String>, CharSequence, Serializable
|
||||
@ -112,7 +112,7 @@ public final class String
|
||||
(offset + " < 0 or " + offset + " + " + length + " > " + l);
|
||||
}
|
||||
|
||||
if(!copy && isUTF8(data)) copy = true;
|
||||
if(!copy && Utf8.test(data)) copy = true;
|
||||
|
||||
if (copy) {
|
||||
Object c;
|
||||
@ -120,7 +120,7 @@ public final class String
|
||||
c = new char[length];
|
||||
System.arraycopy(data, offset, c, 0, length);
|
||||
} else {
|
||||
c = decodeUTF8((byte[])data, offset, length);
|
||||
c = Utf8.decode((byte[])data, offset, length);
|
||||
if(c instanceof char[]) length = ((char[])c).length;
|
||||
}
|
||||
|
||||
@ -134,85 +134,6 @@ public final class String
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isUTF8(Object data) {
|
||||
if(!(data instanceof byte[])) return false;
|
||||
byte[] b = (byte[])data;
|
||||
for(int i = 0; i < b.length; ++i) {
|
||||
if(((int)b[i] & 0x080) != 0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static byte[] encodeUTF8(char[] s16, int offset, int length) {
|
||||
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||
for(int i = offset; i < offset+length; ++i) {
|
||||
char c = s16[i];
|
||||
if(c == '\u0000') { // null char
|
||||
buf.write(0);
|
||||
buf.write(0);
|
||||
} else if(c < 0x080) { // 1 byte char
|
||||
buf.write(c);
|
||||
} else if(c < 0x0800) { // 2 byte char
|
||||
buf.write(0x0c0 | (c >>> 6));
|
||||
buf.write(0x080 | (c & 0x03f));
|
||||
} else { // 3 byte char
|
||||
buf.write(0x0e0 | ((c >>> 12) & 0x0f));
|
||||
buf.write(0x080 | ((c >>> 6) & 0x03f));
|
||||
buf.write(0x080 | (c & 0x03f));
|
||||
}
|
||||
}
|
||||
return buf.toByteArray();
|
||||
}
|
||||
|
||||
private static void decodeUTF8_insert(Object data, int index, int val) {
|
||||
if(data instanceof byte[]) ((byte[])data)[index] = (byte)val;
|
||||
else ((char[])data)[index] = (char)val;
|
||||
}
|
||||
|
||||
private static Object decodeUTF8_widen(Object data, int length, int capacity) {
|
||||
byte[] src = (byte[])data;
|
||||
char[] result = new char[capacity];
|
||||
for(int i = 0; i < length; ++i) result[i] = (char)((int)src[i] & 0x0ff);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Object decodeUTF8_trim(Object data, int length) {
|
||||
if(data instanceof byte[]) return data;
|
||||
if(((char[])data).length == length) return data;
|
||||
char[] result = new char[length];
|
||||
System.arraycopy(data, 0, result, 0, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Object decodeUTF8(byte[] s8, int offset, int length) {
|
||||
Object buf = new byte[length];
|
||||
boolean isMultiByte = false;
|
||||
int i=offset, j=0;
|
||||
while(i < offset+length) {
|
||||
int x = s8[i++];
|
||||
if((x & 0x080) == 0x0) { // 1 byte char
|
||||
if(x == 0) ++i; // 2 byte null char
|
||||
decodeUTF8_insert(buf, j++, x);
|
||||
} else if((x & 0x0e0) == 0x0c0) { // 2 byte char
|
||||
if(!isMultiByte) {
|
||||
buf = decodeUTF8_widen(buf, j, length-1);
|
||||
isMultiByte = true;
|
||||
}
|
||||
int y = s8[i++];
|
||||
decodeUTF8_insert(buf, j++, ((x & 0x1f) << 6) | (y & 0x3f));
|
||||
} else if((x & 0x0f0) == 0x0e0) { // 3 byte char
|
||||
if(!isMultiByte) {
|
||||
buf = decodeUTF8_widen(buf, j, length-2);
|
||||
isMultiByte = true;
|
||||
}
|
||||
int y = s8[i++]; int z = s8[i++];
|
||||
decodeUTF8_insert(buf, j++, ((x & 0xf) << 12) | ((y & 0x3f) << 6) | (z & 0x3f));
|
||||
}
|
||||
}
|
||||
|
||||
return decodeUTF8_trim(buf, j);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this;
|
||||
}
|
||||
@ -494,7 +415,7 @@ public final class String
|
||||
getBytes(0, length, b, 0);
|
||||
return b;
|
||||
}
|
||||
return encodeUTF8((char[])data, offset, length);
|
||||
return Utf8.encode((char[])data, offset, length);
|
||||
}
|
||||
|
||||
public byte[] getBytes(String format)
|
||||
|
19
src/arm.h
19
src/arm.h
@ -69,7 +69,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
||||
uintptr_t gprTable[GprCount];
|
||||
unsigned gprIndex = 0;
|
||||
|
||||
uintptr_t stack[argumentsSize / BytesPerWord];
|
||||
uintptr_t stack[(argumentCount * 8) / BytesPerWord]; // is > argumentSize to account for padding
|
||||
unsigned stackIndex = 0;
|
||||
|
||||
unsigned ai = 0;
|
||||
@ -77,15 +77,18 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
||||
switch (argumentTypes[ati]) {
|
||||
case DOUBLE_TYPE:
|
||||
case INT64_TYPE: {
|
||||
if (gprIndex + (8 / BytesPerWord) <= GprCount) {
|
||||
if (gprIndex + (8 / BytesPerWord) <= GprCount) { // pass argument on registers
|
||||
if (gprIndex & 1) { // 8-byte alignment
|
||||
memset(gprTable + gprIndex, 0, 4); // probably not necessary, but for good luck
|
||||
++gprIndex;
|
||||
}
|
||||
memcpy(gprTable + gprIndex, arguments + ai, 8);
|
||||
gprIndex += 8 / BytesPerWord;
|
||||
} else if (gprIndex == GprCount-1) { // split between last GPR and stack
|
||||
memcpy(gprTable + gprIndex, arguments + ai, 4);
|
||||
++gprIndex;
|
||||
memcpy(stack + stackIndex, arguments + ai + 4, 4);
|
||||
++stackIndex;
|
||||
} else {
|
||||
} else { // pass argument on stack
|
||||
if (stackIndex & 1) { // 8-byte alignment
|
||||
memset(stack + stackIndex, 0, 4); // probably not necessary, but for good luck
|
||||
++stackIndex;
|
||||
}
|
||||
memcpy(stack + stackIndex, arguments + ai, 8);
|
||||
stackIndex += 8 / BytesPerWord;
|
||||
}
|
||||
|
@ -118,9 +118,6 @@ inline void
|
||||
pushDouble(Thread* t, double v)
|
||||
{
|
||||
uint64_t w = doubleToBits(v);
|
||||
#ifdef __arm__
|
||||
w = w << 32 | w >> 32;
|
||||
#endif
|
||||
pushLong(t, w);
|
||||
}
|
||||
|
||||
@ -175,9 +172,6 @@ inline double
|
||||
popDouble(Thread* t)
|
||||
{
|
||||
uint64_t v = popLong(t);
|
||||
#ifdef __arm__
|
||||
v = v << 32 | v >> 32;
|
||||
#endif
|
||||
return bitsToDouble(v);
|
||||
}
|
||||
|
||||
@ -569,15 +563,6 @@ pushResult(Thread* t, unsigned returnCode, uint64_t result, bool indirect)
|
||||
break;
|
||||
|
||||
case DoubleField:
|
||||
#ifdef __arm__
|
||||
result = result << 32 | result >> 32;
|
||||
if (DebugRun) {
|
||||
fprintf(stderr, "result: %"LLD"\n", result);
|
||||
}
|
||||
pushLong(t, result);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case LongField:
|
||||
if (DebugRun) {
|
||||
fprintf(stderr, "result: %"LLD"\n", result);
|
||||
@ -629,15 +614,6 @@ marshalArguments(Thread* t, uintptr_t* args, unsigned i, unsigned count,
|
||||
break;
|
||||
|
||||
case DOUBLE_TYPE:
|
||||
#ifdef __arm__
|
||||
{
|
||||
uint64_t v = peekLong(t, sp);
|
||||
v = v << 32 | v >> 32;
|
||||
memcpy(args + offset, &v, 8);
|
||||
offset += (8 / BytesPerWord);
|
||||
sp += 2;
|
||||
} break;
|
||||
#endif
|
||||
case INT64_TYPE: {
|
||||
uint64_t v = peekLong(t, sp);
|
||||
memcpy(args + offset, &v, 8);
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "util.h"
|
||||
#include "processor.h"
|
||||
#include "constants.h"
|
||||
#include "processor.h"
|
||||
|
||||
using namespace vm;
|
||||
|
||||
|
376
src/powerpc.cpp
376
src/powerpc.cpp
@ -20,29 +20,6 @@ using namespace vm;
|
||||
|
||||
namespace {
|
||||
|
||||
namespace field {
|
||||
// BITFIELD MASKS
|
||||
const int64_t MASK_LO32 = 0x0ffffffff;
|
||||
const int MASK_LO16 = 0x0ffff;
|
||||
const int MASK_LO8 = 0x0ff;
|
||||
// BITFIELD EXTRACTORS
|
||||
inline int lo32(int64_t i) { return (int)(i & MASK_LO32); }
|
||||
inline int hi32(int64_t i) { return lo32(i >> 32); }
|
||||
inline int lo16(int64_t i) { return (int)(i & MASK_LO16); }
|
||||
inline int hi16(int64_t i) { return lo16(i >> 16); }
|
||||
inline int lo8(int64_t i) { return (int)(i & MASK_LO8); }
|
||||
inline int hi8(int64_t i) { return lo8(i >> 8); }
|
||||
|
||||
inline int ha16(int32_t i) {
|
||||
return ((i >> 16) + ((i & 0x8000) ? 1 : 0)) & 0xffff;
|
||||
}
|
||||
|
||||
inline int unha16(int32_t high, int32_t low) {
|
||||
return ((high - ((low & 0x8000) ? 1 : 0)) << 16) | low;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace isa {
|
||||
// INSTRUCTION FORMATS
|
||||
inline int D(int op, int rt, int ra, int d) { return op<<26|rt<<21|ra<<16|(d & 0xFFFF); }
|
||||
@ -155,6 +132,24 @@ inline int cmpwi(int ra, int i) { return cmpi(0, ra, i); }
|
||||
inline int cmplwi(int ra, int i) { return cmpli(0, ra, i); }
|
||||
}
|
||||
|
||||
const int64_t MASK_LO32 = 0x0ffffffff;
|
||||
const int MASK_LO16 = 0x0ffff;
|
||||
const int MASK_LO8 = 0x0ff;
|
||||
inline int lo32(int64_t i) { return (int)(i & MASK_LO32); }
|
||||
inline int hi32(int64_t i) { return lo32(i >> 32); }
|
||||
inline int lo16(int64_t i) { return (int)(i & MASK_LO16); }
|
||||
inline int hi16(int64_t i) { return lo16(i >> 16); }
|
||||
inline int lo8(int64_t i) { return (int)(i & MASK_LO8); }
|
||||
inline int hi8(int64_t i) { return lo8(i >> 8); }
|
||||
|
||||
inline int ha16(int32_t i) {
|
||||
return ((i >> 16) + ((i & 0x8000) ? 1 : 0)) & 0xffff;
|
||||
}
|
||||
|
||||
inline int unha16(int32_t high, int32_t low) {
|
||||
return ((high - ((low & 0x8000) ? 1 : 0)) << 16) | low;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isInt16(intptr_t v)
|
||||
{
|
||||
@ -445,100 +440,94 @@ branchIndex(ArchitectureContext* c UNUSED, OperandType operand1,
|
||||
|
||||
// BEGIN OPERATION COMPILERS
|
||||
|
||||
using namespace field;
|
||||
using namespace isa;
|
||||
|
||||
typedef Assembler::Register Reg;
|
||||
typedef Assembler::Constant Const;
|
||||
|
||||
inline void issue(Context* con, int code) { con->code.append4(code); }
|
||||
inline int getTemp(Context* con) { return con->client->acquireTemporary(); }
|
||||
inline void emit(Context* con, int code) { con->code.append4(code); }
|
||||
inline int newTemp(Context* con) { return con->client->acquireTemporary(); }
|
||||
inline void freeTemp(Context* con, int r) { con->client->releaseTemporary(r); }
|
||||
inline int64_t getVal(Const* c) { return c->value->value(); }
|
||||
inline int R(Reg* r) { return r->low; }
|
||||
inline int H(Reg* r) { return r->high; }
|
||||
inline int64_t getValue(Assembler::Constant* c) { return c->value->value(); }
|
||||
|
||||
|
||||
void shiftLeftR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t)
|
||||
void shiftLeftR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t)
|
||||
{
|
||||
if(size == 8) {
|
||||
Reg Tmp(getTemp(con), getTemp(con)); Reg* tmp = &Tmp;
|
||||
issue(con, subfic(H(tmp), R(a), 32));
|
||||
issue(con, slw(H(t), H(b), R(a)));
|
||||
issue(con, srw(R(tmp), R(b), H(tmp)));
|
||||
issue(con, or_(H(t), H(t), R(tmp)));
|
||||
issue(con, addi(H(tmp), R(a), -32));
|
||||
issue(con, slw(R(tmp), R(b), H(tmp)));
|
||||
issue(con, or_(H(t), H(t), R(tmp)));
|
||||
freeTemp(con, H(tmp)); freeTemp(con, R(tmp));
|
||||
Assembler::Register Tmp(newTemp(con), newTemp(con)); Assembler::Register* tmp = &Tmp;
|
||||
emit(con, subfic(tmp->high, a->low, 32));
|
||||
emit(con, slw(t->high, b->high, a->low));
|
||||
emit(con, srw(tmp->low, b->low, tmp->high));
|
||||
emit(con, or_(t->high, t->high, tmp->low));
|
||||
emit(con, addi(tmp->high, a->low, -32));
|
||||
emit(con, slw(tmp->low, b->low, tmp->high));
|
||||
emit(con, or_(t->high, t->high, tmp->low));
|
||||
freeTemp(con, tmp->high); freeTemp(con, tmp->low);
|
||||
}
|
||||
issue(con, slw(R(t), R(b), R(a)));
|
||||
emit(con, slw(t->low, b->low, a->low));
|
||||
}
|
||||
|
||||
void shiftLeftC(Context* con, unsigned size, Const* a, Reg* b, Reg* t)
|
||||
void shiftLeftC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t)
|
||||
{
|
||||
int sh = getVal(a);
|
||||
int sh = getValue(a);
|
||||
if (size == 8) {
|
||||
if (sh < 32) {
|
||||
issue(con, rlwinm(H(t),H(b),sh,0,31-sh));
|
||||
issue(con, rlwimi(H(t),R(b),sh,32-sh,31));
|
||||
emit(con, rlwinm(t->high,b->high,sh,0,31-sh));
|
||||
emit(con, rlwimi(t->high,b->low,sh,32-sh,31));
|
||||
} else {
|
||||
issue(con, rlwinm(H(t),R(b),sh-32,0,63-sh));
|
||||
issue(con, li(R(t),0));
|
||||
emit(con, rlwinm(t->high,b->low,sh-32,0,63-sh));
|
||||
emit(con, li(t->low,0));
|
||||
}
|
||||
}
|
||||
issue(con, slwi(R(t), R(b), sh));
|
||||
emit(con, slwi(t->low, b->low, sh));
|
||||
}
|
||||
|
||||
void shiftRightR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t)
|
||||
void shiftRightR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t)
|
||||
{
|
||||
if(size == 8) {
|
||||
Reg Tmp(getTemp(con), getTemp(con)); Reg* tmp = &Tmp;
|
||||
issue(con, subfic(H(tmp), R(a), 32));
|
||||
issue(con, srw(R(t), R(b), R(a)));
|
||||
issue(con, slw(R(tmp), H(b), H(tmp)));
|
||||
issue(con, or_(R(t), R(t), R(tmp)));
|
||||
issue(con, addic(H(tmp), R(a), -32));
|
||||
issue(con, sraw(R(tmp), H(b), H(tmp)));
|
||||
issue(con, ble(8));
|
||||
issue(con, ori(R(t), R(tmp), 0));
|
||||
issue(con, sraw(H(t), H(b), R(a)));
|
||||
freeTemp(con, H(tmp)); freeTemp(con, R(tmp));
|
||||
Assembler::Register Tmp(newTemp(con), newTemp(con)); Assembler::Register* tmp = &Tmp;
|
||||
emit(con, subfic(tmp->high, a->low, 32));
|
||||
emit(con, srw(t->low, b->low, a->low));
|
||||
emit(con, slw(tmp->low, b->high, tmp->high));
|
||||
emit(con, or_(t->low, t->low, tmp->low));
|
||||
emit(con, addic(tmp->high, a->low, -32));
|
||||
emit(con, sraw(tmp->low, b->high, tmp->high));
|
||||
emit(con, ble(8));
|
||||
emit(con, ori(t->low, tmp->low, 0));
|
||||
emit(con, sraw(t->high, b->high, a->low));
|
||||
freeTemp(con, tmp->high); freeTemp(con, tmp->low);
|
||||
} else {
|
||||
issue(con, sraw(R(t), R(b), R(a)));
|
||||
emit(con, sraw(t->low, b->low, a->low));
|
||||
}
|
||||
}
|
||||
|
||||
void shiftRightC(Context* con, unsigned size, Const* a, Reg* b, Reg* t)
|
||||
void shiftRightC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t)
|
||||
{
|
||||
int sh = getVal(a);
|
||||
int sh = getValue(a);
|
||||
if(size == 8) {
|
||||
if (sh < 32) {
|
||||
issue(con, rlwinm(R(t),R(b),32-sh,sh,31));
|
||||
issue(con, rlwimi(R(t),H(b),32-sh,0,sh-1));
|
||||
issue(con, srawi(H(t),H(b),sh));
|
||||
emit(con, rlwinm(t->low,b->low,32-sh,sh,31));
|
||||
emit(con, rlwimi(t->low,b->high,32-sh,0,sh-1));
|
||||
emit(con, srawi(t->high,b->high,sh));
|
||||
} else {
|
||||
issue(con, srawi(H(t),H(b),31));
|
||||
issue(con, srawi(R(t),H(b),sh-32));
|
||||
emit(con, srawi(t->high,b->high,31));
|
||||
emit(con, srawi(t->low,b->high,sh-32));
|
||||
}
|
||||
} else {
|
||||
issue(con, srawi(R(t), R(b), sh));
|
||||
emit(con, srawi(t->low, b->low, sh));
|
||||
}
|
||||
}
|
||||
|
||||
void unsignedShiftRightR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t)
|
||||
void unsignedShiftRightR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t)
|
||||
{
|
||||
issue(con, srw(R(t), R(b), R(a)));
|
||||
emit(con, srw(t->low, b->low, a->low));
|
||||
if(size == 8) {
|
||||
Reg Tmp(getTemp(con), getTemp(con)); Reg* tmp = &Tmp;
|
||||
issue(con, subfic(H(tmp), R(a), 32));
|
||||
issue(con, slw(R(tmp), H(b), H(tmp)));
|
||||
issue(con, or_(R(t), R(t), R(tmp)));
|
||||
issue(con, addi(H(tmp), R(a), -32));
|
||||
issue(con, srw(R(tmp), H(b), H(tmp)));
|
||||
issue(con, or_(R(t), R(t), R(tmp)));
|
||||
issue(con, srw(H(t), H(b), R(a)));
|
||||
freeTemp(con, H(tmp)); freeTemp(con, R(tmp));
|
||||
Assembler::Register Tmp(newTemp(con), newTemp(con)); Assembler::Register* tmp = &Tmp;
|
||||
emit(con, subfic(tmp->high, a->low, 32));
|
||||
emit(con, slw(tmp->low, b->high, tmp->high));
|
||||
emit(con, or_(t->low, t->low, tmp->low));
|
||||
emit(con, addi(tmp->high, a->low, -32));
|
||||
emit(con, srw(tmp->low, b->high, tmp->high));
|
||||
emit(con, or_(t->low, t->low, tmp->low));
|
||||
emit(con, srw(t->high, b->high, a->low));
|
||||
freeTemp(con, tmp->high); freeTemp(con, tmp->low);
|
||||
}
|
||||
}
|
||||
|
||||
@ -546,24 +535,24 @@ void
|
||||
moveRR(Context* c, unsigned srcSize, Assembler::Register* src,
|
||||
unsigned dstSize, Assembler::Register* dst);
|
||||
|
||||
void unsignedShiftRightC(Context* con, unsigned size, Const* a, Reg* b, Reg* t)
|
||||
void unsignedShiftRightC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t)
|
||||
{
|
||||
int sh = getVal(a);
|
||||
int sh = getValue(a);
|
||||
if (size == 8) {
|
||||
if (sh == 32) {
|
||||
Assembler::Register high(b->high);
|
||||
moveRR(con, 4, &high, 4, t);
|
||||
issue(con, li(H(t),0));
|
||||
emit(con, li(t->high,0));
|
||||
} else if (sh < 32) {
|
||||
issue(con, srwi(R(t), R(b), sh));
|
||||
issue(con, rlwimi(R(t),H(b),32-sh,0,sh-1));
|
||||
issue(con, rlwinm(H(t),H(b),32-sh,sh,31));
|
||||
emit(con, srwi(t->low, b->low, sh));
|
||||
emit(con, rlwimi(t->low,b->high,32-sh,0,sh-1));
|
||||
emit(con, rlwinm(t->high,b->high,32-sh,sh,31));
|
||||
} else {
|
||||
issue(con, rlwinm(R(t),H(b),64-sh,sh-32,31));
|
||||
issue(con, li(H(t),0));
|
||||
emit(con, rlwinm(t->low,b->high,64-sh,sh-32,31));
|
||||
emit(con, li(t->high,0));
|
||||
}
|
||||
} else {
|
||||
issue(con, srwi(R(t), R(b), sh));
|
||||
emit(con, srwi(t->low, b->low, sh));
|
||||
}
|
||||
}
|
||||
|
||||
@ -683,8 +672,8 @@ jumpR(Context* c, unsigned size UNUSED, Assembler::Register* target)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
|
||||
issue(c, mtctr(target->low));
|
||||
issue(c, bctr());
|
||||
emit(c, mtctr(target->low));
|
||||
emit(c, bctr());
|
||||
}
|
||||
|
||||
void
|
||||
@ -707,18 +696,18 @@ moveRR(Context* c, unsigned srcSize, Assembler::Register* src,
|
||||
{
|
||||
switch (srcSize) {
|
||||
case 1:
|
||||
issue(c, extsb(dst->low, src->low));
|
||||
emit(c, extsb(dst->low, src->low));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
issue(c, extsh(dst->low, src->low));
|
||||
emit(c, extsh(dst->low, src->low));
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 8:
|
||||
if (srcSize == 4 and dstSize == 8) {
|
||||
moveRR(c, 4, src, 4, dst);
|
||||
issue(c, srawi(dst->high, src->low, 31));
|
||||
emit(c, srawi(dst->high, src->low, 31));
|
||||
} else if (srcSize == 8 and dstSize == 8) {
|
||||
Assembler::Register srcHigh(src->high);
|
||||
Assembler::Register dstHigh(dst->high);
|
||||
@ -735,7 +724,7 @@ moveRR(Context* c, unsigned srcSize, Assembler::Register* src,
|
||||
moveRR(c, 4, &srcHigh, 4, &dstHigh);
|
||||
}
|
||||
} else if (src->low != dst->low) {
|
||||
issue(c, mr(dst->low, src->low));
|
||||
emit(c, mr(dst->low, src->low));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -749,7 +738,7 @@ moveZRR(Context* c, unsigned srcSize, Assembler::Register* src,
|
||||
{
|
||||
switch (srcSize) {
|
||||
case 2:
|
||||
issue(c, andi(dst->low, src->low, 0xFFFF));
|
||||
emit(c, andi(dst->low, src->low, 0xFFFF));
|
||||
break;
|
||||
|
||||
default: abort(c);
|
||||
@ -764,16 +753,16 @@ moveCR2(Context* c, unsigned, Assembler::Constant* src,
|
||||
if (src->value->resolved()) {
|
||||
int32_t v = src->value->value();
|
||||
if (isInt16(v)) {
|
||||
issue(c, li(dst->low, v));
|
||||
emit(c, li(dst->low, v));
|
||||
} else {
|
||||
issue(c, lis(dst->low, v >> 16));
|
||||
issue(c, ori(dst->low, dst->low, v));
|
||||
emit(c, lis(dst->low, v >> 16));
|
||||
emit(c, ori(dst->low, dst->low, v));
|
||||
}
|
||||
} else {
|
||||
appendImmediateTask
|
||||
(c, src->value, offset(c), BytesPerWord, promiseOffset, false);
|
||||
issue(c, lis(dst->low, 0));
|
||||
issue(c, ori(dst->low, dst->low, 0));
|
||||
emit(c, lis(dst->low, 0));
|
||||
emit(c, ori(dst->low, dst->low, 0));
|
||||
}
|
||||
} else {
|
||||
abort(c); // todo
|
||||
@ -787,38 +776,38 @@ moveCR(Context* c, unsigned srcSize, Assembler::Constant* src,
|
||||
moveCR2(c, srcSize, src, dstSize, dst, 0);
|
||||
}
|
||||
|
||||
void addR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
||||
void addR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) {
|
||||
if(size == 8) {
|
||||
issue(con, addc(R(t), R(a), R(b)));
|
||||
issue(con, adde(H(t), H(a), H(b)));
|
||||
emit(con, addc(t->low, a->low, b->low));
|
||||
emit(con, adde(t->high, a->high, b->high));
|
||||
} else {
|
||||
issue(con, add(R(t), R(a), R(b)));
|
||||
emit(con, add(t->low, a->low, b->low));
|
||||
}
|
||||
}
|
||||
|
||||
void addC(Context* con, unsigned size, Const* a, Reg* b, Reg* t) {
|
||||
void addC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) {
|
||||
assert(con, size == BytesPerWord);
|
||||
|
||||
int32_t i = getVal(a);
|
||||
int32_t i = getValue(a);
|
||||
if(i) {
|
||||
issue(con, addi(R(t), R(b), lo16(i)));
|
||||
emit(con, addi(t->low, b->low, lo16(i)));
|
||||
if(not isInt16(i))
|
||||
issue(con, addis(R(t), R(t), hi16(i) + carry16(i)));
|
||||
emit(con, addis(t->low, t->low, hi16(i) + carry16(i)));
|
||||
} else {
|
||||
moveRR(con, size, b, size, t);
|
||||
}
|
||||
}
|
||||
|
||||
void subR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
||||
void subR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) {
|
||||
if(size == 8) {
|
||||
issue(con, subfc(R(t), R(a), R(b)));
|
||||
issue(con, subfe(H(t), H(a), H(b)));
|
||||
emit(con, subfc(t->low, a->low, b->low));
|
||||
emit(con, subfe(t->high, a->high, b->high));
|
||||
} else {
|
||||
issue(con, subf(R(t), R(a), R(b)));
|
||||
emit(con, subf(t->low, a->low, b->low));
|
||||
}
|
||||
}
|
||||
|
||||
void subC(Context* c, unsigned size, Const* a, Reg* b, Reg* t) {
|
||||
void subC(Context* c, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) {
|
||||
assert(c, size == BytesPerWord);
|
||||
|
||||
ResolvedPromise promise(- a->value->value());
|
||||
@ -826,7 +815,7 @@ void subC(Context* c, unsigned size, Const* a, Reg* b, Reg* t) {
|
||||
addC(c, size, &constant, b, t);
|
||||
}
|
||||
|
||||
void multiplyR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
||||
void multiplyR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) {
|
||||
if(size == 8) {
|
||||
bool useTemporaries = b->low == t->low;
|
||||
int tmpLow;
|
||||
@ -839,28 +828,28 @@ void multiplyR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
||||
tmpHigh = t->high;
|
||||
}
|
||||
|
||||
issue(con, mullw(tmpHigh, H(a), R(b)));
|
||||
issue(con, mullw(tmpLow, R(a), H(b)));
|
||||
issue(con, add(H(t), tmpHigh, tmpLow));
|
||||
issue(con, mulhwu(tmpLow, R(a), R(b)));
|
||||
issue(con, add(H(t), H(t), tmpLow));
|
||||
issue(con, mullw(R(t), R(a), R(b)));
|
||||
emit(con, mullw(tmpHigh, a->high, b->low));
|
||||
emit(con, mullw(tmpLow, a->low, b->high));
|
||||
emit(con, add(t->high, tmpHigh, tmpLow));
|
||||
emit(con, mulhwu(tmpLow, a->low, b->low));
|
||||
emit(con, add(t->high, t->high, tmpLow));
|
||||
emit(con, mullw(t->low, a->low, b->low));
|
||||
|
||||
if (useTemporaries) {
|
||||
con->client->releaseTemporary(tmpLow);
|
||||
con->client->releaseTemporary(tmpHigh);
|
||||
}
|
||||
} else {
|
||||
issue(con, mullw(R(t), R(a), R(b)));
|
||||
emit(con, mullw(t->low, a->low, b->low));
|
||||
}
|
||||
}
|
||||
|
||||
void divideR(Context* con, unsigned size UNUSED, Reg* a, Reg* b, Reg* t) {
|
||||
void divideR(Context* con, unsigned size UNUSED, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) {
|
||||
assert(con, size == 4);
|
||||
issue(con, divw(R(t), R(b), R(a)));
|
||||
emit(con, divw(t->low, b->low, a->low));
|
||||
}
|
||||
|
||||
void remainderR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
||||
void remainderR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) {
|
||||
bool useTemporary = b->low == t->low;
|
||||
Assembler::Register tmp(t->low);
|
||||
if (useTemporary) {
|
||||
@ -935,15 +924,15 @@ store(Context* c, unsigned size, Assembler::Register* src,
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
issue(c, stbx(src->low, base, normalized));
|
||||
emit(c, stbx(src->low, base, normalized));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
issue(c, sthx(src->low, base, normalized));
|
||||
emit(c, sthx(src->low, base, normalized));
|
||||
break;
|
||||
|
||||
case 4:
|
||||
issue(c, stwx(src->low, base, normalized));
|
||||
emit(c, stwx(src->low, base, normalized));
|
||||
break;
|
||||
|
||||
case 8: {
|
||||
@ -959,15 +948,15 @@ store(Context* c, unsigned size, Assembler::Register* src,
|
||||
} else {
|
||||
switch (size) {
|
||||
case 1:
|
||||
issue(c, stb(src->low, base, offset));
|
||||
emit(c, stb(src->low, base, offset));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
issue(c, sth(src->low, base, offset));
|
||||
emit(c, sth(src->low, base, offset));
|
||||
break;
|
||||
|
||||
case 4:
|
||||
issue(c, stw(src->low, base, offset));
|
||||
emit(c, stw(src->low, base, offset));
|
||||
break;
|
||||
|
||||
case 8: {
|
||||
@ -998,12 +987,12 @@ moveAndUpdateRM(Context* c, unsigned srcSize UNUSED, Assembler::Register* src,
|
||||
assert(c, dstSize == BytesPerWord);
|
||||
|
||||
if (dst->index == NoRegister) {
|
||||
issue(c, stwu(src->low, dst->base, dst->offset));
|
||||
emit(c, stwu(src->low, dst->base, dst->offset));
|
||||
} else {
|
||||
assert(c, dst->offset == 0);
|
||||
assert(c, dst->scale == 1);
|
||||
|
||||
issue(c, stwux(src->low, dst->base, dst->index));
|
||||
emit(c, stwux(src->low, dst->base, dst->index));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1019,17 +1008,17 @@ load(Context* c, unsigned srcSize, int base, int offset, int index,
|
||||
|
||||
switch (srcSize) {
|
||||
case 1:
|
||||
issue(c, lbzx(dst->low, base, normalized));
|
||||
emit(c, lbzx(dst->low, base, normalized));
|
||||
if (signExtend) {
|
||||
issue(c, extsb(dst->low, dst->low));
|
||||
emit(c, extsb(dst->low, dst->low));
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (signExtend) {
|
||||
issue(c, lhax(dst->low, base, normalized));
|
||||
emit(c, lhax(dst->low, base, normalized));
|
||||
} else {
|
||||
issue(c, lhzx(dst->low, base, normalized));
|
||||
emit(c, lhzx(dst->low, base, normalized));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1043,7 +1032,7 @@ load(Context* c, unsigned srcSize, int base, int offset, int index,
|
||||
load(c, 4, base, 0, normalized, 1, 4, &dstHigh, preserveIndex, false);
|
||||
load(c, 4, base, 4, normalized, 1, 4, dst, preserveIndex, false);
|
||||
} else {
|
||||
issue(c, lwzx(dst->low, base, normalized));
|
||||
emit(c, lwzx(dst->low, base, normalized));
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -1054,22 +1043,22 @@ load(Context* c, unsigned srcSize, int base, int offset, int index,
|
||||
} else {
|
||||
switch (srcSize) {
|
||||
case 1:
|
||||
issue(c, lbz(dst->low, base, offset));
|
||||
emit(c, lbz(dst->low, base, offset));
|
||||
if (signExtend) {
|
||||
issue(c, extsb(dst->low, dst->low));
|
||||
emit(c, extsb(dst->low, dst->low));
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (signExtend) {
|
||||
issue(c, lha(dst->low, base, offset));
|
||||
emit(c, lha(dst->low, base, offset));
|
||||
} else {
|
||||
issue(c, lha(dst->low, base, offset));
|
||||
emit(c, lha(dst->low, base, offset));
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
issue(c, lwz(dst->low, base, offset));
|
||||
emit(c, lwz(dst->low, base, offset));
|
||||
break;
|
||||
|
||||
case 8: {
|
||||
@ -1078,7 +1067,7 @@ load(Context* c, unsigned srcSize, int base, int offset, int index,
|
||||
load(c, 4, base, offset, NoRegister, 1, 4, &dstHigh, false, false);
|
||||
load(c, 4, base, offset + 4, NoRegister, 1, 4, dst, false, false);
|
||||
} else {
|
||||
issue(c, lwzx(dst->low, base, offset));
|
||||
emit(c, lwzx(dst->low, base, offset));
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -1103,19 +1092,6 @@ moveZMR(Context* c, unsigned srcSize, Assembler::Memory* src,
|
||||
dstSize, dst, true, false);
|
||||
}
|
||||
|
||||
// void moveCR3(Context* con, unsigned aSize, Const* a, unsigned tSize, Reg* t) {
|
||||
// int64_t i = getVal(a);
|
||||
// if(tSize == 8) {
|
||||
// int64_t j;
|
||||
// if(aSize == 8) j = i; // 64-bit const -> load high bits into high register
|
||||
// else j = 0; // 32-bit const -> clear high register
|
||||
// issue(con, lis(H(t), hi16(hi32(j))));
|
||||
// issue(con, ori(H(t), H(t), lo16(hi32(j))));
|
||||
// }
|
||||
// issue(con, lis(R(t), hi16(i)));
|
||||
// issue(con, ori(R(t), R(t), lo16(i)));
|
||||
// }
|
||||
|
||||
void
|
||||
andR(Context* c, unsigned size, Assembler::Register* a,
|
||||
Assembler::Register* b, Assembler::Register* dst)
|
||||
@ -1128,7 +1104,7 @@ andR(Context* c, unsigned size, Assembler::Register* a,
|
||||
andR(c, 4, a, b, dst);
|
||||
andR(c, 4, &ah, &bh, &dh);
|
||||
} else {
|
||||
issue(c, and_(dst->low, a->low, b->low));
|
||||
emit(c, and_(dst->low, a->low, b->low));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1181,9 +1157,9 @@ andC(Context* c, unsigned size, Assembler::Constant* a,
|
||||
// the topmost or bottommost 16 bits are zero.
|
||||
|
||||
if ((v32 >> 16) == 0) {
|
||||
issue(c, andi(dst->low, b->low, v32));
|
||||
emit(c, andi(dst->low, b->low, v32));
|
||||
} else if ((v32 & 0xFFFF) == 0) {
|
||||
issue(c, andis(dst->low, b->low, v32 >> 16));
|
||||
emit(c, andis(dst->low, b->low, v32 >> 16));
|
||||
} else {
|
||||
bool useTemporary = b->low == dst->low;
|
||||
Assembler::Register tmp(dst->low);
|
||||
@ -1206,12 +1182,12 @@ andC(Context* c, unsigned size, Assembler::Constant* a,
|
||||
|
||||
if (state) {
|
||||
if (start != 0 or end != 31) {
|
||||
issue(c, rlwinm(dst->low, b->low, 0, 31 - end, 31 - start));
|
||||
emit(c, rlwinm(dst->low, b->low, 0, 31 - end, 31 - start));
|
||||
} else {
|
||||
moveRR(c, 4, b, 4, dst);
|
||||
}
|
||||
} else {
|
||||
issue(c, li(dst->low, 0));
|
||||
emit(c, li(dst->low, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1228,7 +1204,7 @@ orR(Context* c, unsigned size, Assembler::Register* a,
|
||||
orR(c, 4, a, b, dst);
|
||||
orR(c, 4, &ah, &bh, &dh);
|
||||
} else {
|
||||
issue(c, or_(dst->low, a->low, b->low));
|
||||
emit(c, or_(dst->low, a->low, b->low));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1251,9 +1227,9 @@ orC(Context* c, unsigned size, Assembler::Constant* a,
|
||||
orC(c, 4, &al, b, dst);
|
||||
orC(c, 4, &ah, &bh, &dh);
|
||||
} else {
|
||||
issue(c, ori(b->low, dst->low, v));
|
||||
emit(c, ori(b->low, dst->low, v));
|
||||
if (v >> 16) {
|
||||
issue(c, oris(dst->low, dst->low, v >> 16));
|
||||
emit(c, oris(dst->low, dst->low, v >> 16));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1270,7 +1246,7 @@ xorR(Context* c, unsigned size, Assembler::Register* a,
|
||||
xorR(c, 4, a, b, dst);
|
||||
xorR(c, 4, &ah, &bh, &dh);
|
||||
} else {
|
||||
issue(c, xor_(dst->low, a->low, b->low));
|
||||
emit(c, xor_(dst->low, a->low, b->low));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1294,10 +1270,10 @@ xorC(Context* c, unsigned size, Assembler::Constant* a,
|
||||
xorC(c, 4, &ah, &bh, &dh);
|
||||
} else {
|
||||
if (v >> 16) {
|
||||
issue(c, xoris(b->low, dst->low, v >> 16));
|
||||
issue(c, xori(dst->low, dst->low, v));
|
||||
emit(c, xoris(b->low, dst->low, v >> 16));
|
||||
emit(c, xori(dst->low, dst->low, v));
|
||||
} else {
|
||||
issue(c, xori(b->low, dst->low, v));
|
||||
emit(c, xori(b->low, dst->low, v));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1313,7 +1289,7 @@ moveAR2(Context* c, unsigned srcSize UNUSED, Assembler::Address* src,
|
||||
appendImmediateTask
|
||||
(c, src->address, offset(c), BytesPerWord, promiseOffset, true);
|
||||
|
||||
issue(c, lis(dst->low, 0));
|
||||
emit(c, lis(dst->low, 0));
|
||||
moveMR(c, dstSize, &memory, dstSize, dst);
|
||||
}
|
||||
|
||||
@ -1330,7 +1306,7 @@ compareRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a,
|
||||
{
|
||||
assert(c, aSize == 4 and bSize == 4);
|
||||
|
||||
issue(c, cmpw(b->low, a->low));
|
||||
emit(c, cmpw(b->low, a->low));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1340,7 +1316,7 @@ compareCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||
assert(c, aSize == 4 and bSize == 4);
|
||||
|
||||
if (a->value->resolved() and isInt16(a->value->value())) {
|
||||
issue(c, cmpwi(b->low, a->value->value()));
|
||||
emit(c, cmpwi(b->low, a->value->value()));
|
||||
} else {
|
||||
Assembler::Register tmp(c->client->acquireTemporary());
|
||||
moveCR(c, aSize, a, bSize, &tmp);
|
||||
@ -1379,7 +1355,7 @@ compareUnsignedRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a,
|
||||
{
|
||||
assert(c, aSize == 4 and bSize == 4);
|
||||
|
||||
issue(c, cmplw(b->low, a->low));
|
||||
emit(c, cmplw(b->low, a->low));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1389,7 +1365,7 @@ compareUnsignedCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||
assert(c, aSize == 4 and bSize == 4);
|
||||
|
||||
if (a->value->resolved() and (a->value->value() >> 16) == 0) {
|
||||
issue(c, cmplwi(b->low, a->value->value()));
|
||||
emit(c, cmplwi(b->low, a->value->value()));
|
||||
} else {
|
||||
Assembler::Register tmp(c->client->acquireTemporary());
|
||||
moveCR(c, aSize, a, bSize, &tmp);
|
||||
@ -1429,7 +1405,7 @@ void
|
||||
conditional(Context* c, int32_t branch, Assembler::Constant* target)
|
||||
{
|
||||
appendOffsetTask(c, target->value, offset(c), true);
|
||||
issue(c, branch);
|
||||
emit(c, branch);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1452,7 +1428,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al,
|
||||
switch (op) {
|
||||
case JumpIfEqual:
|
||||
next = c->code.length();
|
||||
issue(c, bne(0));
|
||||
emit(c, bne(0));
|
||||
|
||||
compareSigned(c, 4, al, 4, bl);
|
||||
conditional(c, beq(0), target);
|
||||
@ -1469,7 +1445,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al,
|
||||
conditional(c, blt(0), target);
|
||||
|
||||
next = c->code.length();
|
||||
issue(c, bgt(0));
|
||||
emit(c, bgt(0));
|
||||
|
||||
compareUnsigned(c, 4, al, 4, bl);
|
||||
conditional(c, blt(0), target);
|
||||
@ -1479,7 +1455,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al,
|
||||
conditional(c, bgt(0), target);
|
||||
|
||||
next = c->code.length();
|
||||
issue(c, blt(0));
|
||||
emit(c, blt(0));
|
||||
|
||||
compareUnsigned(c, 4, al, 4, bl);
|
||||
conditional(c, bgt(0), target);
|
||||
@ -1489,7 +1465,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al,
|
||||
conditional(c, blt(0), target);
|
||||
|
||||
next = c->code.length();
|
||||
issue(c, bgt(0));
|
||||
emit(c, bgt(0));
|
||||
|
||||
compareUnsigned(c, 4, al, 4, bl);
|
||||
conditional(c, ble(0), target);
|
||||
@ -1499,7 +1475,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al,
|
||||
conditional(c, bgt(0), target);
|
||||
|
||||
next = c->code.length();
|
||||
issue(c, blt(0));
|
||||
emit(c, blt(0));
|
||||
|
||||
compareUnsigned(c, 4, al, 4, bl);
|
||||
conditional(c, bge(0), target);
|
||||
@ -1621,10 +1597,10 @@ negateRR(Context* c, unsigned srcSize, Assembler::Register* src,
|
||||
if (srcSize == 8) {
|
||||
Assembler::Register dstHigh(dst->high);
|
||||
|
||||
issue(c, subfic(dst->low, src->low, 0));
|
||||
issue(c, subfze(dst->high, src->high));
|
||||
emit(c, subfic(dst->low, src->low, 0));
|
||||
emit(c, subfze(dst->high, src->high));
|
||||
} else {
|
||||
issue(c, neg(dst->low, src->low));
|
||||
emit(c, neg(dst->low, src->low));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1633,8 +1609,8 @@ callR(Context* c, unsigned size UNUSED, Assembler::Register* target)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
|
||||
issue(c, mtctr(target->low));
|
||||
issue(c, bctrl());
|
||||
emit(c, mtctr(target->low));
|
||||
emit(c, bctrl());
|
||||
}
|
||||
|
||||
void
|
||||
@ -1643,7 +1619,7 @@ callC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
||||
assert(c, size == BytesPerWord);
|
||||
|
||||
appendOffsetTask(c, target->value, offset(c), false);
|
||||
issue(c, bl(0));
|
||||
emit(c, bl(0));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1696,7 +1672,7 @@ jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
||||
assert(c, size == BytesPerWord);
|
||||
|
||||
appendOffsetTask(c, target->value, offset(c), false);
|
||||
issue(c, b(0));
|
||||
emit(c, b(0));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1705,7 +1681,7 @@ jumpIfEqualC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
||||
assert(c, size == BytesPerWord);
|
||||
|
||||
appendOffsetTask(c, target->value, offset(c), true);
|
||||
issue(c, beq(0));
|
||||
emit(c, beq(0));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1714,7 +1690,7 @@ jumpIfNotEqualC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
||||
assert(c, size == BytesPerWord);
|
||||
|
||||
appendOffsetTask(c, target->value, offset(c), true);
|
||||
issue(c, bne(0));
|
||||
emit(c, bne(0));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1723,7 +1699,7 @@ jumpIfGreaterC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
||||
assert(c, size == BytesPerWord);
|
||||
|
||||
appendOffsetTask(c, target->value, offset(c), true);
|
||||
issue(c, bgt(0));
|
||||
emit(c, bgt(0));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1733,7 +1709,7 @@ jumpIfGreaterOrEqualC(Context* c, unsigned size UNUSED,
|
||||
assert(c, size == BytesPerWord);
|
||||
|
||||
appendOffsetTask(c, target->value, offset(c), true);
|
||||
issue(c, bge(0));
|
||||
emit(c, bge(0));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1742,7 +1718,7 @@ jumpIfLessC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
||||
assert(c, size == BytesPerWord);
|
||||
|
||||
appendOffsetTask(c, target->value, offset(c), true);
|
||||
issue(c, blt(0));
|
||||
emit(c, blt(0));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1752,19 +1728,19 @@ jumpIfLessOrEqualC(Context* c, unsigned size UNUSED,
|
||||
assert(c, size == BytesPerWord);
|
||||
|
||||
appendOffsetTask(c, target->value, offset(c), true);
|
||||
issue(c, ble(0));
|
||||
emit(c, ble(0));
|
||||
}
|
||||
|
||||
void
|
||||
return_(Context* c)
|
||||
{
|
||||
issue(c, blr());
|
||||
emit(c, blr());
|
||||
}
|
||||
|
||||
void
|
||||
memoryBarrier(Context* c)
|
||||
{
|
||||
issue(c, sync(0));
|
||||
emit(c, sync(0));
|
||||
}
|
||||
|
||||
// END OPERATION COMPILERS
|
||||
@ -2268,7 +2244,7 @@ class MyAssembler: public Assembler {
|
||||
|
||||
virtual void allocateFrame(unsigned footprint) {
|
||||
Register returnAddress(0);
|
||||
issue(&c, mflr(returnAddress.low));
|
||||
emit(&c, mflr(returnAddress.low));
|
||||
|
||||
Memory returnAddressDst(StackRegister, 8);
|
||||
moveRM(&c, BytesPerWord, &returnAddress, BytesPerWord, &returnAddressDst);
|
||||
@ -2296,7 +2272,7 @@ class MyAssembler: public Assembler {
|
||||
Memory returnAddressSrc(StackRegister, 8);
|
||||
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &returnAddress);
|
||||
|
||||
issue(&c, mtlr(returnAddress.low));
|
||||
emit(&c, mtlr(returnAddress.low));
|
||||
}
|
||||
|
||||
virtual void popFrameForTailCall(unsigned footprint,
|
||||
@ -2310,7 +2286,7 @@ class MyAssembler: public Assembler {
|
||||
Memory returnAddressSrc(StackRegister, 8 + (footprint * BytesPerWord));
|
||||
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &tmp);
|
||||
|
||||
issue(&c, mtlr(tmp.low));
|
||||
emit(&c, mtlr(tmp.low));
|
||||
|
||||
Memory stackSrc(StackRegister, footprint * BytesPerWord);
|
||||
moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &tmp);
|
||||
|
Loading…
Reference in New Issue
Block a user