Implementing breakpoint condition evaluator in C, refactoring Java version
This commit is contained in:
parent
2df99895fa
commit
1386d36b0d
2
makefile
2
makefile
|
@ -10,7 +10,7 @@ default:
|
||||||
@echo
|
@echo
|
||||||
@echo "Planet Virtual Boy Emulator"
|
@echo "Planet Virtual Boy Emulator"
|
||||||
@echo " https://www.planetvb.com/"
|
@echo " https://www.planetvb.com/"
|
||||||
@echo " August 11, 2020"
|
@echo " August 14, 2020"
|
||||||
@echo
|
@echo
|
||||||
@echo "Intended build environment: Debian i386 or amd64"
|
@echo "Intended build environment: Debian i386 or amd64"
|
||||||
@echo " gcc-multilib"
|
@echo " gcc-multilib"
|
||||||
|
|
|
@ -0,0 +1,636 @@
|
||||||
|
// This file is included through NativeVUE.c and cannot be built directly. */
|
||||||
|
#ifdef NATIVEVUE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constants //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Token types
|
||||||
|
#define BINARY 4
|
||||||
|
#define FLOAT 1
|
||||||
|
#define UNARY 3
|
||||||
|
#define SYMBOL 2
|
||||||
|
#define WORD 0
|
||||||
|
|
||||||
|
// CPU stages
|
||||||
|
#define EXCEPTION 2
|
||||||
|
#define EXECUTE 1
|
||||||
|
|
||||||
|
// Operator IDs
|
||||||
|
#define ADD 2
|
||||||
|
#define BITWISE_AND 3
|
||||||
|
#define BITWISE_NOT 4
|
||||||
|
#define BITWISE_OR 5
|
||||||
|
#define BITWISE_XOR 6
|
||||||
|
#define CEIL 7
|
||||||
|
#define DIVIDE 8
|
||||||
|
#define EQUAL 9
|
||||||
|
#define FLOOR 10
|
||||||
|
//#define FLOAT 1 // Same as type
|
||||||
|
#define GREATER_EQUAL_SIGNED 11
|
||||||
|
#define GREATER_EQUAL_UNSIGNED 12
|
||||||
|
#define GREATER_SIGNED 13
|
||||||
|
#define GREATER_UNSIGNED 14
|
||||||
|
#define GROUP 15
|
||||||
|
#define LESS_EQUAL_SIGNED 16
|
||||||
|
#define LESS_EQUAL_UNSIGNED 17
|
||||||
|
#define LESS_SIGNED 18
|
||||||
|
#define LESS_UNSIGNED 19
|
||||||
|
#define LOGICAL_AND 20
|
||||||
|
#define LOGICAL_NOT 21
|
||||||
|
#define LOGICAL_OR 22
|
||||||
|
#define LOGICAL_XOR 23
|
||||||
|
#define MULTIPLY 24
|
||||||
|
#define NEGATE 25
|
||||||
|
#define NOT_EQUAL 26
|
||||||
|
#define READ_WORD 27
|
||||||
|
#define REMAINDER 28
|
||||||
|
#define ROUND 29
|
||||||
|
#define SHIFT_LEFT 30
|
||||||
|
#define SHIFT_RIGHT 31
|
||||||
|
#define SHIFT_RIGHT_ARITHMETIC 32
|
||||||
|
#define SUBTRACT 33
|
||||||
|
#define TRUNC 34
|
||||||
|
//#define WORD 0 // Same as type
|
||||||
|
#define XFLOAT 35
|
||||||
|
#define XWORD 36
|
||||||
|
|
||||||
|
// Functional symbol IDs
|
||||||
|
#define ADDRESS 0
|
||||||
|
#define CODE 1
|
||||||
|
#define COND 2
|
||||||
|
#define DISP 3
|
||||||
|
#define FORMAT 4
|
||||||
|
#define ID 5
|
||||||
|
#define IMM 6
|
||||||
|
#define OPCODE 7
|
||||||
|
#define REG1 8
|
||||||
|
#define REG2 9
|
||||||
|
#define REGID 10
|
||||||
|
#define SIZE 11
|
||||||
|
#define SUBOPCODE 12
|
||||||
|
#define VALUE 13
|
||||||
|
#define VECTOR 14
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Evaluation Helpers //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Resolve a float from word bits
|
||||||
|
static float asFloat(int32_t value) {
|
||||||
|
return *(float *)&value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve the word bits of a float
|
||||||
|
static int32_t asWord(float value) {
|
||||||
|
int32_t bits = *(int32_t *)&value;
|
||||||
|
int32_t exp = bits & 0x7F800000;
|
||||||
|
int32_t digits = bits & 0x007FFFFF;
|
||||||
|
return
|
||||||
|
!(bits & 0x7FFFFFFF) || // Zero
|
||||||
|
exp == 0x7F800000 || // Indefinite
|
||||||
|
!exp && digits != 0 // Denormal
|
||||||
|
? 0 : bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert a float to a word
|
||||||
|
static int32_t toWord(float value) {
|
||||||
|
value = roundf(value);
|
||||||
|
return value>=0x7FFFFFFF || value<(int32_t)0x80000000 ? 0 : (int) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Binary Functions //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Evaluate +
|
||||||
|
static int32_t evalAdd(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
return leftWord && rightWord ? leftValue + rightValue : asWord(
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) +
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate &
|
||||||
|
static int32_t evalBitwiseAnd(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
return (leftWord ? leftValue : toWord(asFloat(leftValue ))) &
|
||||||
|
(rightWord ? rightValue : toWord(asFloat(rightValue)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate |
|
||||||
|
static int32_t evalBitwiseOr(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
return (leftWord ? leftValue : toWord(asFloat(leftValue ))) |
|
||||||
|
(rightWord ? rightValue : toWord(asFloat(rightValue)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate ^
|
||||||
|
static int32_t evalBitwiseXOr(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
return (leftWord ? leftValue : toWord(asFloat(leftValue ))) ^
|
||||||
|
(rightWord ? rightValue : toWord(asFloat(rightValue)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate /
|
||||||
|
static int32_t evalDivide(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
return !(rightWord ? rightValue : rightValue & 0x7FFFFFFF) ? 0 :
|
||||||
|
leftWord && rightWord ? leftValue / rightValue : asWord(
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) /
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate ==
|
||||||
|
static int32_t evalEqual(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
return leftWord && rightWord ? leftValue == rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) ==
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate >=
|
||||||
|
static int32_t evalGreaterEqualSigned(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
return leftWord && rightWord ? leftValue >= rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) >=
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate >=_
|
||||||
|
static int32_t evalGreaterEqualUnsigned(
|
||||||
|
int32_t leftWord,uint32_t leftValue,int32_t rightWord,uint32_t rightValue){
|
||||||
|
return leftWord && rightWord ? leftValue >= rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) >=
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate >
|
||||||
|
static int32_t evalGreaterSigned(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
return leftWord && rightWord ? leftValue > rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) >
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate >_
|
||||||
|
static int32_t evalGreaterUnsigned(
|
||||||
|
int32_t leftWord,uint32_t leftValue,int32_t rightWord,uint32_t rightValue){
|
||||||
|
return leftWord && rightWord ? leftValue > rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) >
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate <=
|
||||||
|
static int32_t evalLessEqualSigned(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
return leftWord && rightWord ? leftValue <= rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) <=
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate <=_
|
||||||
|
static int32_t evalLessEqualUnsigned(
|
||||||
|
int32_t leftWord,uint32_t leftValue,int32_t rightWord,uint32_t rightValue){
|
||||||
|
return leftWord && rightWord ? leftValue <= rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) <=
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate <
|
||||||
|
static int32_t evalLessSigned(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
return leftWord && rightWord ? leftValue < rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) <
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate <_
|
||||||
|
static int32_t evalLessUnsigned(
|
||||||
|
int32_t leftWord,uint32_t leftValue,int32_t rightWord,uint32_t rightValue){
|
||||||
|
return leftWord && rightWord ? leftValue < rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) <
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate *
|
||||||
|
static int32_t evalMultiply(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
return leftWord && rightWord ? leftValue * rightValue : asWord(
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) *
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate !=
|
||||||
|
static int32_t evalNotEqual(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
return leftWord && rightWord ? leftValue != rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) !=
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate %
|
||||||
|
static int32_t evalRemainder(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
return !(rightWord ? rightValue : rightValue & 0x7FFFFFFF) ? 0 :
|
||||||
|
leftWord && rightWord ? leftValue % rightValue : asWord(fmodf(
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )),
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate <<
|
||||||
|
static int32_t evalShiftLeft(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
leftValue = leftWord ? leftValue : toWord(asFloat(leftValue ));
|
||||||
|
leftValue = (rightWord ? rightValue : toWord(asFloat(rightValue))) & 31;
|
||||||
|
return leftValue << rightValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate >>
|
||||||
|
static int32_t evalShiftRightArithmetic(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
leftValue = leftWord ? leftValue : toWord(asFloat(leftValue ));
|
||||||
|
leftValue = (rightWord ? rightValue : toWord(asFloat(rightValue))) & 31;
|
||||||
|
return !rightValue ? leftValue :
|
||||||
|
leftValue >> rightValue & (1 << 32 - rightValue) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate >>>
|
||||||
|
static int32_t evalShiftRight(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
leftValue = leftWord ? leftValue : toWord(asFloat(leftValue ));
|
||||||
|
leftValue = (rightWord ? rightValue : toWord(asFloat(rightValue))) & 31;
|
||||||
|
if (!rightValue)
|
||||||
|
return leftValue;
|
||||||
|
leftValue >>= rightValue;
|
||||||
|
rightValue = 32 - rightValue;
|
||||||
|
return SIGN_EXTEND(rightValue, leftValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate -
|
||||||
|
static int32_t evalSubtract(
|
||||||
|
int32_t leftWord,int32_t leftValue,int32_t rightWord,int32_t rightValue) {
|
||||||
|
return leftWord && rightWord ? leftValue - rightValue : asWord(
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) -
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Symbol Functions //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Evaluate address
|
||||||
|
static int32_t evalAddress(VUE *vue) {
|
||||||
|
if (vue->cpu.inst.format == 6)
|
||||||
|
return vue->cpu.program[vue->cpu.inst.reg1] + vue->cpu.inst.disp;
|
||||||
|
switch (vue->cpu.inst.id) {
|
||||||
|
case VUE_BCOND: case VUE_JAL: case VUE_JMP: case VUE_JR:
|
||||||
|
return vue->cpu.pc + vue->cpu.inst.disp;
|
||||||
|
case VUE_RETI:
|
||||||
|
return vue->cpu.psw_np ? vue->cpu.fepc : vue->cpu.eipc;
|
||||||
|
case VUE_TRAP:
|
||||||
|
return 0xFFFFFFA0 + vue->cpu.inst.imm & 0xFFFFFFF0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate cond
|
||||||
|
static int32_t evalCond(VUE *vue) {
|
||||||
|
switch (vue->cpu.inst.id) {
|
||||||
|
case VUE_BCOND: return vue->cpu.inst.cond;
|
||||||
|
case VUE_SETF : return vue->cpu.inst.imm;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate disp
|
||||||
|
static int32_t evalDisp(VUE *vue) {
|
||||||
|
switch (vue->cpu.inst.format) {
|
||||||
|
case 3: case 4: case 6: return vue->cpu.inst.disp;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate imm
|
||||||
|
static int32_t evalImm(VUE *vue) {
|
||||||
|
switch (vue->cpu.inst.format) {
|
||||||
|
case 2: case 5: return vue->cpu.inst.imm;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate reg1
|
||||||
|
static int32_t evalReg1(VUE *vue) {
|
||||||
|
switch (vue->cpu.inst.format) {
|
||||||
|
case 1: case 5: case 6: case 7: return vue->cpu.inst.reg1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate reg2
|
||||||
|
static int32_t evalReg2(VUE *vue) {
|
||||||
|
switch (vue->cpu.inst.format) {
|
||||||
|
case 1: case 2: case 5: case 6: case 7: return vue->cpu.inst.reg2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate regid
|
||||||
|
static int32_t evalRegId(VUE *vue) {
|
||||||
|
switch (vue->cpu.inst.id) {
|
||||||
|
case VUE_LDSR: case VUE_STSR: return vue->cpu.inst.imm;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate subopcode
|
||||||
|
static int32_t evalSubopcode(VUE *vue) {
|
||||||
|
switch (vue->cpu.inst.opcode) {
|
||||||
|
case 0x1F: return vue->cpu.inst.imm;
|
||||||
|
case 0x3E: return vue->cpu.inst.subopcode;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate value
|
||||||
|
static int evalValue(VUE *vue) {
|
||||||
|
return vue->cpu.inst.format == 6 ? vue->cpu.access.value : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate vector
|
||||||
|
static int evalVector(VUE *vue) {
|
||||||
|
return vue->cpu.inst.id == VUE_TRAP ? vue->cpu.inst.imm : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Unary Functions //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Evaluate ~
|
||||||
|
static int32_t evalBitwiseNot(int32_t isWord, int32_t value) {
|
||||||
|
return isWord ? ~value : ~toWord(asFloat(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate !
|
||||||
|
static int32_t evalLogicalNot(int32_t isWord, int32_t value) {
|
||||||
|
return isWord ? !value : !asFloat(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate -
|
||||||
|
static int32_t evalNegate(int32_t isWord, int32_t value) {
|
||||||
|
return isWord ? -value : asWord(-asFloat(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate ceil
|
||||||
|
static int32_t evalCeil(int32_t isWord, int32_t value) {
|
||||||
|
return isWord ? value : asWord(ceilf(asFloat(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate float
|
||||||
|
static int32_t evalFloat(int32_t isWord, int32_t value) {
|
||||||
|
return isWord ? asWord((float) value) : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate floor
|
||||||
|
static int32_t evalFloor(int32_t isWord, int32_t value) {
|
||||||
|
return isWord ? value : asWord(floorf(asFloat(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate []
|
||||||
|
static int32_t evalReadWord(int32_t isWord, int32_t value, VUE *vue) {
|
||||||
|
return vueRead(vue, isWord ? value : toWord(asFloat(value)), VUE_S32);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate round
|
||||||
|
static int32_t evalRound(int32_t isWord, int32_t value) {
|
||||||
|
return isWord ? value : asWord(roundf(asFloat(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate trunc
|
||||||
|
static int32_t evalTrunc(int32_t isWord, int32_t value) {
|
||||||
|
return isWord ? value : asWord(truncf(asFloat(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate word
|
||||||
|
static int32_t evalWord(int32_t isWord, int32_t value) {
|
||||||
|
return isWord ? value : toWord(asFloat(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate xfloat
|
||||||
|
static int32_t evalXFloat(int32_t isWord, int32_t value) {
|
||||||
|
return isWord ? asWord(asFloat(value)) : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Evaluation Functions //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Evaluate a binary operator
|
||||||
|
static int32_t evalBinary(int32_t id, int32_t *stack, int32_t size) {
|
||||||
|
int32_t rv = stack[size - 1];
|
||||||
|
int32_t rt = stack[size - 2];
|
||||||
|
int32_t rw = rt == WORD;
|
||||||
|
int32_t lv = stack[size - 3];
|
||||||
|
int32_t lt = stack[size - 4];
|
||||||
|
int32_t lw = lt == WORD;
|
||||||
|
int32_t type = rw && lw ? WORD : FLOAT;
|
||||||
|
int32_t value = 0;
|
||||||
|
switch (id) {
|
||||||
|
|
||||||
|
// Arithmetic
|
||||||
|
case ADD :
|
||||||
|
value = evalAdd (lw, lv, rw, rv); break;
|
||||||
|
case DIVIDE :
|
||||||
|
value = evalDivide (lw, lv, rw, rv); break;
|
||||||
|
case MULTIPLY :
|
||||||
|
value = evalMultiply (lw, lv, rw, rv); break;
|
||||||
|
case REMAINDER :
|
||||||
|
value = evalRemainder (lw, lv, rw, rv); break;
|
||||||
|
case SUBTRACT :
|
||||||
|
value = evalSubtract (lw, lv, rw, rv); break;
|
||||||
|
default:
|
||||||
|
type = WORD; switch (id) {
|
||||||
|
|
||||||
|
// Bitwise
|
||||||
|
case BITWISE_AND :
|
||||||
|
value = evalBitwiseAnd (lw, lv, rw, rv); break;
|
||||||
|
case BITWISE_OR :
|
||||||
|
value = evalBitwiseOr (lw, lv, rw, rv); break;
|
||||||
|
case BITWISE_XOR :
|
||||||
|
value = evalBitwiseXOr (lw, lv, rw, rv); break;
|
||||||
|
case SHIFT_LEFT :
|
||||||
|
value = evalShiftLeft (lw, lv, rw, rv); break;
|
||||||
|
case SHIFT_RIGHT :
|
||||||
|
value = evalShiftRight (lw, lv, rw, rv); break;
|
||||||
|
case SHIFT_RIGHT_ARITHMETIC:
|
||||||
|
value = evalShiftRightArithmetic(lw, lv, rw, rv); break;
|
||||||
|
|
||||||
|
// Relational
|
||||||
|
case EQUAL :
|
||||||
|
value = evalEqual (lw, lv, rw, rv); break;
|
||||||
|
case GREATER_EQUAL_SIGNED :
|
||||||
|
value = evalGreaterEqualSigned (lw, lv, rw, rv); break;
|
||||||
|
case GREATER_EQUAL_UNSIGNED:
|
||||||
|
value = evalGreaterEqualUnsigned(lw, lv, rw, rv); break;
|
||||||
|
case GREATER_SIGNED :
|
||||||
|
value = evalGreaterSigned (lw, lv, rw, rv); break;
|
||||||
|
case GREATER_UNSIGNED :
|
||||||
|
value = evalGreaterUnsigned (lw, lv, rw, rv); break;
|
||||||
|
case LESS_EQUAL_SIGNED :
|
||||||
|
value = evalLessEqualSigned (lw, lv, rw, rv); break;
|
||||||
|
case LESS_EQUAL_UNSIGNED :
|
||||||
|
value = evalLessEqualUnsigned (lw, lv, rw, rv); break;
|
||||||
|
case LESS_SIGNED :
|
||||||
|
value = evalLessSigned (lw, lv, rw, rv); break;
|
||||||
|
case LESS_UNSIGNED :
|
||||||
|
value = evalLessUnsigned (lw, lv, rw, rv); break;
|
||||||
|
case NOT_EQUAL :
|
||||||
|
value = evalNotEqual (lw, lv, rw, rv); break;
|
||||||
|
|
||||||
|
// Logical
|
||||||
|
default:
|
||||||
|
lw = (lv & (lw ? 0xFFFFFFFF : 0x7FFFFFFF)) != 0;
|
||||||
|
rw = (rv & (rw ? 0xFFFFFFFF : 0x7FFFFFFF)) != 0;
|
||||||
|
|
||||||
|
// Evaluate &&
|
||||||
|
case LOGICAL_AND:
|
||||||
|
type = lt; value = lv;
|
||||||
|
if (lw)
|
||||||
|
{ type = rt; value = rv; }
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Evaluate ||
|
||||||
|
case LOGICAL_OR:
|
||||||
|
type = lt; value = lv;
|
||||||
|
if (!lw)
|
||||||
|
{ type = rt; value = rv; }
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Evaluate ^^
|
||||||
|
case LOGICAL_XOR:
|
||||||
|
type = rt; value = rv;
|
||||||
|
if (lw == rw)
|
||||||
|
{ type = WORD; value = 0; }
|
||||||
|
else if (lw)
|
||||||
|
{ type = lt; value = lv; }
|
||||||
|
break;
|
||||||
|
}}
|
||||||
|
stack[size - 4] = type;
|
||||||
|
stack[size - 3] = value;
|
||||||
|
return size - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate a functional symbol
|
||||||
|
static int32_t evalSymbol(VUE *vue, int32_t id, int32_t *stack, int32_t size) {
|
||||||
|
int32_t ret = 0;
|
||||||
|
if (id == VUE_PC)
|
||||||
|
ret = vue->cpu.pc;
|
||||||
|
else if (id >= 200)
|
||||||
|
ret = vueGetRegister(vue, id - 200, VUE_TRUE);
|
||||||
|
else if (id >= 100)
|
||||||
|
ret = vue->cpu.program[id - 100];
|
||||||
|
else if (vue->cpu.stage == EXCEPTION && id == CODE)
|
||||||
|
ret = vue->cpu.exception.code;
|
||||||
|
else if (vue->cpu.stage == EXECUTE) switch (id) {
|
||||||
|
case ADDRESS : ret = evalAddress (vue); break;
|
||||||
|
case COND : ret = evalCond (vue); break;
|
||||||
|
case DISP : ret = evalDisp (vue); break;
|
||||||
|
case FORMAT : ret = vue->cpu.inst.format; break;
|
||||||
|
case ID : ret = vue->cpu.inst.id ; break;
|
||||||
|
case IMM : ret = evalImm (vue); break;
|
||||||
|
case OPCODE : ret = vue->cpu.inst.opcode; break;
|
||||||
|
case REG1 : ret = evalReg1 (vue); break;
|
||||||
|
case REG2 : ret = evalReg2 (vue); break;
|
||||||
|
case REGID : ret = evalRegId (vue); break;
|
||||||
|
case SIZE : ret = vue->cpu.inst.size ; break;
|
||||||
|
case SUBOPCODE: ret = evalSubopcode (vue); break;
|
||||||
|
case VALUE : ret = evalValue (vue); break;
|
||||||
|
case VECTOR : ret = evalVector (vue); break;
|
||||||
|
}
|
||||||
|
stack[size++] = WORD;
|
||||||
|
stack[size++] = ret;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate a unary operator
|
||||||
|
static void evalUnary(VUE *vue, int32_t id, int32_t *stack, int32_t size) {
|
||||||
|
int32_t type = stack[size - 2];
|
||||||
|
int32_t value = stack[size - 1];
|
||||||
|
int32_t isWord = type == WORD;
|
||||||
|
switch (id) {
|
||||||
|
case BITWISE_NOT: value = evalBitwiseNot(isWord, value);
|
||||||
|
type = WORD ; break;
|
||||||
|
case LOGICAL_NOT: value = evalLogicalNot(isWord, value);
|
||||||
|
type = WORD ; break;
|
||||||
|
case NEGATE : value = evalNegate (isWord, value); break;
|
||||||
|
case CEIL : value = evalCeil (isWord, value); break;
|
||||||
|
case FLOAT : value = evalFloat (isWord, value);
|
||||||
|
type = FLOAT; break;
|
||||||
|
case FLOOR : value = evalFloor (isWord, value); break;
|
||||||
|
case READ_WORD : value = evalReadWord (isWord, value, vue);
|
||||||
|
type = WORD ; break;
|
||||||
|
case ROUND : value = evalRound (isWord, value); break;
|
||||||
|
case TRUNC : value = evalTrunc (isWord, value); break;
|
||||||
|
case WORD : value = evalWord (isWord, value);
|
||||||
|
type = WORD ; break;
|
||||||
|
case XFLOAT : value = evalXFloat (isWord, value);
|
||||||
|
type = FLOAT; break;
|
||||||
|
case XWORD : type = WORD;
|
||||||
|
}
|
||||||
|
stack[size - 2] = type;
|
||||||
|
stack[size - 1] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate a breakpoint condition for an emulation context
|
||||||
|
int32_t evaluate(VUE *vue, BREAKPOINT *brk, int32_t *stack) {
|
||||||
|
|
||||||
|
// The condition is empty
|
||||||
|
if (brk->numCondition == 0)
|
||||||
|
return brk->enabled;
|
||||||
|
|
||||||
|
// Process tokens
|
||||||
|
int size = 0;
|
||||||
|
for (int x = 0; x < brk->numCondition; x++) {
|
||||||
|
TOKEN *tok = &brk->condition[x];
|
||||||
|
switch (tok->type) {
|
||||||
|
case BINARY: size =
|
||||||
|
evalBinary( tok->value, stack, size); continue;
|
||||||
|
case SYMBOL: size =
|
||||||
|
evalSymbol(vue, tok->value, stack, size); continue;
|
||||||
|
case UNARY :
|
||||||
|
evalUnary (vue, tok->value, stack, size); continue;
|
||||||
|
}
|
||||||
|
stack[size++] = tok->type;
|
||||||
|
stack[size++] = tok->value;
|
||||||
|
}
|
||||||
|
return (stack[1] & (stack[0] == WORD ? 0xFFFFFFFF : 0x7FFFFFFF)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // NATIVEVUE
|
|
@ -33,55 +33,55 @@ public class Breakpoint {
|
||||||
public static final int UNEXPECTED = 7;
|
public static final int UNEXPECTED = 7;
|
||||||
|
|
||||||
// Token types
|
// Token types
|
||||||
private static final int BINARY = 1;
|
private static final int BINARY = 4;
|
||||||
private static final int CLOSE = 2;
|
private static final int CLOSE = 6;
|
||||||
private static final int FLOAT = 3;
|
private static final int FLOAT = 1;
|
||||||
private static final int OPEN = 4;
|
private static final int UNARY = 3;
|
||||||
private static final int SYMBOL = 5;
|
private static final int OPEN = 5;
|
||||||
private static final int UNARY = 6;
|
private static final int SYMBOL = 2;
|
||||||
private static final int WORD = 0;
|
private static final int WORD = 0;
|
||||||
|
|
||||||
// Expected token modes adjacent to any given token
|
// Expected token modes adjacent to any given token
|
||||||
// 0 = Value, unary or open expected, 1 = Binary or close expected
|
// 0 = Value, unary or open expected, 1 = Binary or close expected
|
||||||
private static final int MODES_AFTER = 0b0101101;
|
private static final int MODES_AFTER = 0b1000111;
|
||||||
private static final int MODES_BEFORE = 0b0000110;
|
private static final int MODES_BEFORE = 0b1010000;
|
||||||
|
|
||||||
// Operator IDs
|
// Operator IDs
|
||||||
private static final int ADD = 0;
|
private static final int ADD = 2;
|
||||||
private static final int BITWISE_AND = 1;
|
private static final int BITWISE_AND = 3;
|
||||||
private static final int BITWISE_NOT = 2;
|
private static final int BITWISE_NOT = 4;
|
||||||
private static final int BITWISE_OR = 3;
|
private static final int BITWISE_OR = 5;
|
||||||
private static final int BITWISE_XOR = 4;
|
private static final int BITWISE_XOR = 6;
|
||||||
private static final int CEIL = 5;
|
private static final int CEIL = 7;
|
||||||
private static final int DIVIDE = 6;
|
private static final int DIVIDE = 8;
|
||||||
private static final int EQUAL = 7;
|
private static final int EQUAL = 9;
|
||||||
private static final int FLOATOP = 8;
|
private static final int FLOOR = 10;
|
||||||
private static final int FLOOR = 9;
|
//private static final int FLOAT = 1; // Same as type
|
||||||
private static final int GREATER_EQUAL_SIGNED = 10;
|
private static final int GREATER_EQUAL_SIGNED = 11;
|
||||||
private static final int GREATER_EQUAL_UNSIGNED = 11;
|
private static final int GREATER_EQUAL_UNSIGNED = 12;
|
||||||
private static final int GREATER_SIGNED = 12;
|
private static final int GREATER_SIGNED = 13;
|
||||||
private static final int GREATER_UNSIGNED = 13;
|
private static final int GREATER_UNSIGNED = 14;
|
||||||
private static final int GROUP = 14;
|
private static final int GROUP = 15;
|
||||||
private static final int LESS_EQUAL_SIGNED = 15;
|
private static final int LESS_EQUAL_SIGNED = 16;
|
||||||
private static final int LESS_EQUAL_UNSIGNED = 16;
|
private static final int LESS_EQUAL_UNSIGNED = 17;
|
||||||
private static final int LESS_SIGNED = 17;
|
private static final int LESS_SIGNED = 18;
|
||||||
private static final int LESS_UNSIGNED = 18;
|
private static final int LESS_UNSIGNED = 19;
|
||||||
private static final int LOGICAL_AND = 19;
|
private static final int LOGICAL_AND = 20;
|
||||||
private static final int LOGICAL_NOT = 20;
|
private static final int LOGICAL_NOT = 21;
|
||||||
private static final int LOGICAL_OR = 21;
|
private static final int LOGICAL_OR = 22;
|
||||||
private static final int LOGICAL_XOR = 22;
|
private static final int LOGICAL_XOR = 23;
|
||||||
private static final int MULTIPLY = 23;
|
private static final int MULTIPLY = 24;
|
||||||
private static final int NEGATE = 24;
|
private static final int NEGATE = 25;
|
||||||
private static final int NOT_EQUAL = 25;
|
private static final int NOT_EQUAL = 26;
|
||||||
private static final int READ_WORD = 26;
|
private static final int READ_WORD = 27;
|
||||||
private static final int REMAINDER = 27;
|
private static final int REMAINDER = 28;
|
||||||
private static final int ROUND = 28;
|
private static final int ROUND = 29;
|
||||||
private static final int SHIFT_LEFT = 29;
|
private static final int SHIFT_LEFT = 30;
|
||||||
private static final int SHIFT_RIGHT = 30;
|
private static final int SHIFT_RIGHT = 31;
|
||||||
private static final int SHIFT_RIGHT_ARITHMETIC = 31;
|
private static final int SHIFT_RIGHT_ARITHMETIC = 32;
|
||||||
private static final int SUBTRACT = 32;
|
private static final int SUBTRACT = 33;
|
||||||
private static final int TRUNC = 33;
|
private static final int TRUNC = 34;
|
||||||
private static final int WORDOP = 34;
|
//private static final int WORD = 0; // Same as type
|
||||||
private static final int XFLOAT = 35;
|
private static final int XFLOAT = 35;
|
||||||
private static final int XWORD = 36;
|
private static final int XWORD = 36;
|
||||||
|
|
||||||
|
@ -122,11 +122,11 @@ public class Breakpoint {
|
||||||
OPDEFS.put("!" , new OpDef( 1, UNARY , LOGICAL_NOT ));
|
OPDEFS.put("!" , new OpDef( 1, UNARY , LOGICAL_NOT ));
|
||||||
OPDEFS.put("-" , new OpDef( 1, UNARY , NEGATE ));
|
OPDEFS.put("-" , new OpDef( 1, UNARY , NEGATE ));
|
||||||
OPDEFS.put("ceil" , new OpDef( 1, UNARY , CEIL ));
|
OPDEFS.put("ceil" , new OpDef( 1, UNARY , CEIL ));
|
||||||
OPDEFS.put("float" , new OpDef( 1, UNARY , FLOATOP ));
|
OPDEFS.put("float" , new OpDef( 1, UNARY , FLOAT ));
|
||||||
OPDEFS.put("floor" , new OpDef( 1, UNARY , FLOOR ));
|
OPDEFS.put("floor" , new OpDef( 1, UNARY , FLOOR ));
|
||||||
OPDEFS.put("round" , new OpDef( 1, UNARY , ROUND ));
|
OPDEFS.put("round" , new OpDef( 1, UNARY , ROUND ));
|
||||||
OPDEFS.put("trunc" , new OpDef( 1, UNARY , TRUNC ));
|
OPDEFS.put("trunc" , new OpDef( 1, UNARY , TRUNC ));
|
||||||
OPDEFS.put("word" , new OpDef( 1, UNARY , WORDOP ));
|
OPDEFS.put("word" , new OpDef( 1, UNARY , WORD ));
|
||||||
OPDEFS.put("xfloat", new OpDef( 1, UNARY , XFLOAT ));
|
OPDEFS.put("xfloat", new OpDef( 1, UNARY , XFLOAT ));
|
||||||
OPDEFS.put("xword" , new OpDef( 1, UNARY , XWORD ));
|
OPDEFS.put("xword" , new OpDef( 1, UNARY , XWORD ));
|
||||||
OPDEFS.put("/" , new OpDef( 2, BINARY, DIVIDE ));
|
OPDEFS.put("/" , new OpDef( 2, BINARY, DIVIDE ));
|
||||||
|
@ -233,16 +233,20 @@ public class Breakpoint {
|
||||||
SYMDEFS.put("lp" , 131);
|
SYMDEFS.put("lp" , 131);
|
||||||
|
|
||||||
// System register symbol definitions
|
// System register symbol definitions
|
||||||
SYMDEFS.put("adtre", 225); SYMDEFS.put("fepsw", 203);
|
SYMDEFS.put("adtre", 200 + VUE.ADTRE);
|
||||||
SYMDEFS.put("chcw" , 224); SYMDEFS.put("pc" , 199);
|
SYMDEFS.put("chcw" , 200 + VUE.CHCW );
|
||||||
SYMDEFS.put("ecr" , 204); SYMDEFS.put("psw" , 205);
|
SYMDEFS.put("ecr" , 200 + VUE.ECR );
|
||||||
SYMDEFS.put("eipc" , 200); SYMDEFS.put("sr29" , 229);
|
SYMDEFS.put("eipc" , 200 + VUE.EIPC );
|
||||||
SYMDEFS.put("eipsw", 201); SYMDEFS.put("sr31" , 231);
|
SYMDEFS.put("eipsw", 200 + VUE.EIPSW);
|
||||||
SYMDEFS.put("fepc" , 202);
|
SYMDEFS.put("fepc" , 200 + VUE.FEPC );
|
||||||
|
SYMDEFS.put("fepsw", 200 + VUE.FEPSW);
|
||||||
|
SYMDEFS.put("pc" , VUE.PC );
|
||||||
|
SYMDEFS.put("psw" , 200 + VUE.PSW );
|
||||||
|
SYMDEFS.put("sr29" , 229 );
|
||||||
|
SYMDEFS.put("sr31" , 231 );
|
||||||
LITDEFS.put("pir" , 0x00005346);
|
LITDEFS.put("pir" , 0x00005346);
|
||||||
LITDEFS.put("tkcw" , 0x000000E0);
|
LITDEFS.put("tkcw" , 0x000000E0);
|
||||||
LITDEFS.put("sr30" , 0x00000004);
|
LITDEFS.put("sr30" , 0x00000004);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -473,6 +477,30 @@ public class Breakpoint {
|
||||||
// Package Methods //
|
// Package Methods //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Evaluate the condition for an emulation context
|
||||||
|
boolean evaluate(JavaVUE vue, int[] stack) {
|
||||||
|
|
||||||
|
// The condition is empty
|
||||||
|
if (tokens.length == 0)
|
||||||
|
return isEnabled && errCode == NONE;
|
||||||
|
|
||||||
|
// Process tokens
|
||||||
|
int size = 0;
|
||||||
|
for (var tok : tokens) {
|
||||||
|
switch (tok.type) {
|
||||||
|
case BINARY: size =
|
||||||
|
evalBinary( tok.id, stack, size); continue;
|
||||||
|
case SYMBOL: size =
|
||||||
|
evalSymbol(vue, tok.id, stack, size); continue;
|
||||||
|
case UNARY :
|
||||||
|
evalUnary (vue, tok.id, stack, size); continue;
|
||||||
|
}
|
||||||
|
stack[size++] = tok.type;
|
||||||
|
stack[size++] = tok.value;
|
||||||
|
}
|
||||||
|
return (stack[1] & (stack[0] == WORD ? 0xFFFFFFFF : 0x7FFFFFFF)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Determine the required stack size to evaluate the expression
|
// Determine the required stack size to evaluate the expression
|
||||||
int depth() {
|
int depth() {
|
||||||
|
|
||||||
|
@ -849,253 +877,134 @@ public class Breakpoint {
|
||||||
// Evaluation Methods //
|
// Evaluation Methods //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Evaluate the condition for an emulation context
|
// Resolve a float from word bits
|
||||||
boolean evaluate(JavaVUE vue, int[] stack) {
|
private static float asFloat(int value) {
|
||||||
|
return Float.intBitsToFloat(value);
|
||||||
|
}
|
||||||
|
|
||||||
// The condition is empty
|
// Resolve the word bits of a float
|
||||||
if (tokens.length == 0)
|
private static int asWord(float value) {
|
||||||
return isEnabled && errCode == NONE;
|
return Float.floatToRawIntBits(fixFloat(value));
|
||||||
|
}
|
||||||
|
|
||||||
// Process tokens
|
// Convert an unsigned word to a float
|
||||||
int size = 0;
|
private static float ufloat(int value) {
|
||||||
for (var tok : tokens) {
|
return (float) (value & 0xFFFFFFFFL);
|
||||||
switch (tok.type) {
|
}
|
||||||
//case BINARY: size =
|
|
||||||
// evalBinary(vue, tok.id, stack, size); continue;
|
// Convert a float to a word
|
||||||
case SYMBOL: size =
|
private static int toWord(float value) {
|
||||||
evalSymbol(vue, tok.id, stack, size); continue;
|
value = (float) Math.round(value);
|
||||||
case UNARY : size =
|
return value >= 0x7FFFFFFF || value < 0x80000000 ? 0 : (int) value;
|
||||||
evalUnary (vue, tok.id, stack, size); continue;
|
|
||||||
}
|
|
||||||
stack[size++] = tok.type;
|
|
||||||
stack[size++] = tok.value;
|
|
||||||
}
|
|
||||||
return (stack[1] & (stack[0] == FLOAT ? 0x7FFFFFFF : 0xFFFFFFFF)) != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate a binary operator
|
// Evaluate a binary operator
|
||||||
private int evalBinary(JavaVUE vue, int id, int[] stack, int size) {
|
private static int evalBinary(int id, int[] stack, int size) {
|
||||||
int lw = stack[size - 3];
|
int rv = stack[size - 1];
|
||||||
float lf = Float.intBitsToFloat(lw);
|
int rt = stack[size - 2];
|
||||||
int ret = 0;
|
boolean rw = rt == WORD;
|
||||||
int rw = stack[size - 1];
|
int lv = stack[size - 3];
|
||||||
float rf = Float.intBitsToFloat(rw);
|
int lt = stack[size - 4];
|
||||||
int type = stack[size - 2] | stack[size - 4];
|
boolean lw = lt == WORD;
|
||||||
|
int type = rw && lw ? WORD : FLOAT;
|
||||||
|
int value = 0;
|
||||||
switch (id) {
|
switch (id) {
|
||||||
|
|
||||||
|
// Arithmetic
|
||||||
case ADD :
|
case ADD :
|
||||||
ret = evalAdd (type, lw, lf, rw, rf); break;
|
value = evalAdd (lw, lv, rw, rv); break;
|
||||||
case BITWISE_AND :
|
|
||||||
ret = evalBitwiseAnd (type, lw, lf, rw, rf); break;
|
|
||||||
case BITWISE_XOR :
|
|
||||||
ret = evalBitwiseXOr (type, lw, lf, rw, rf); break;
|
|
||||||
case BITWISE_OR :
|
|
||||||
ret = evalBitwiseOr (type, lw, lf, rw, rf); break;
|
|
||||||
case DIVIDE :
|
case DIVIDE :
|
||||||
ret = evalDivide (type, lw, lf, rw, rf); break;
|
value = evalDivide (lw, lv, rw, rv); break;
|
||||||
case EQUAL :
|
|
||||||
ret = evalEqual (type, lw, lf, rw, rf);
|
|
||||||
type = WORD; break;
|
|
||||||
case GREATER_EQUAL_SIGNED :
|
|
||||||
ret = evalGreaterEqualSigned (type, lw, lf, rw, rf);
|
|
||||||
type = WORD; break;
|
|
||||||
case GREATER_EQUAL_UNSIGNED:
|
|
||||||
ret = evalGreaterEqualUnsigned(type, lw, lf, rw, rf);
|
|
||||||
type = WORD; break;
|
|
||||||
case GREATER_SIGNED :
|
|
||||||
ret = evalGreaterSigned (type, lw, lf, rw, rf);
|
|
||||||
type = WORD; break;
|
|
||||||
case GREATER_UNSIGNED :
|
|
||||||
ret = evalGreaterUnsigned (type, lw, lf, rw, rf);
|
|
||||||
type = WORD; break;
|
|
||||||
case LESS_EQUAL_SIGNED :
|
|
||||||
ret = evalLessEqualSigned (type, lw, lf, rw, rf);
|
|
||||||
type = WORD; break;
|
|
||||||
case LESS_EQUAL_UNSIGNED :
|
|
||||||
ret = evalLessEqualUnsigned (type, lw, lf, rw, rf);
|
|
||||||
type = WORD; break;
|
|
||||||
case LESS_SIGNED :
|
|
||||||
ret = evalLessSigned (type, lw, lf, rw, rf);
|
|
||||||
type = WORD; break;
|
|
||||||
case LESS_UNSIGNED :
|
|
||||||
ret = evalLessUnsigned (type, lw, lf, rw, rf);
|
|
||||||
type = WORD; break;
|
|
||||||
case LOGICAL_AND :
|
|
||||||
ret = evalLogicalAnd (type, lw, lf, rw, rf);
|
|
||||||
type = WORD; break;
|
|
||||||
case LOGICAL_OR :
|
|
||||||
ret = evalLogicalOr (type, lw, lf, rw, rf);
|
|
||||||
type = WORD; break;
|
|
||||||
case LOGICAL_XOR :
|
|
||||||
ret = evalLogicalXOr (type, lw, lf, rw, rf);
|
|
||||||
type = WORD; break;
|
|
||||||
case MULTIPLY :
|
case MULTIPLY :
|
||||||
ret = evalMultiply (type, lw, lf, rw, rf); break;
|
value = evalMultiply (lw, lv, rw, rv); break;
|
||||||
case NOT_EQUAL :
|
|
||||||
ret = evalNotEqual (type, lw, lf, rw, rf);
|
|
||||||
type = WORD; break;
|
|
||||||
case REMAINDER :
|
case REMAINDER :
|
||||||
ret = evalRemainder (type, lw, lf, rw, rf); break;
|
value = evalRemainder (lw, lv, rw, rv); break;
|
||||||
case SHIFT_LEFT :
|
|
||||||
ret = evalShiftLeft (type, lw, lf, rw, rf); break;
|
|
||||||
case SHIFT_RIGHT :
|
|
||||||
ret = evalShiftRight (type, lw, lf, rw, rf); break;
|
|
||||||
case SHIFT_RIGHT_ARITHMETIC:
|
|
||||||
ret = evalShiftRightArithmetic(type, lw, lf, rw, rf); break;
|
|
||||||
case SUBTRACT :
|
case SUBTRACT :
|
||||||
ret = evalSubtract (type, lw, lf, rw, rf); break;
|
value = evalSubtract (lw, lv, rw, rv); break;
|
||||||
}
|
default:
|
||||||
|
type = WORD; switch (id) {
|
||||||
|
|
||||||
|
// Bitwise
|
||||||
|
case BITWISE_AND :
|
||||||
|
value = evalBitwiseAnd (lw, lv, rw, rv); break;
|
||||||
|
case BITWISE_OR :
|
||||||
|
value = evalBitwiseOr (lw, lv, rw, rv); break;
|
||||||
|
case BITWISE_XOR :
|
||||||
|
value = evalBitwiseXOr (lw, lv, rw, rv); break;
|
||||||
|
case SHIFT_LEFT :
|
||||||
|
value = evalShiftLeft (lw, lv, rw, rv); break;
|
||||||
|
case SHIFT_RIGHT :
|
||||||
|
value = evalShiftRight (lw, lv, rw, rv); break;
|
||||||
|
case SHIFT_RIGHT_ARITHMETIC:
|
||||||
|
value = evalShiftRightArithmetic(lw, lv, rw, rv); break;
|
||||||
|
|
||||||
|
// Relational
|
||||||
|
case EQUAL :
|
||||||
|
value = evalEqual (lw, lv, rw, rv); break;
|
||||||
|
case GREATER_EQUAL_SIGNED :
|
||||||
|
value = evalGreaterEqualSigned (lw, lv, rw, rv); break;
|
||||||
|
case GREATER_EQUAL_UNSIGNED:
|
||||||
|
value = evalGreaterEqualUnsigned(lw, lv, rw, rv); break;
|
||||||
|
case GREATER_SIGNED :
|
||||||
|
value = evalGreaterSigned (lw, lv, rw, rv); break;
|
||||||
|
case GREATER_UNSIGNED :
|
||||||
|
value = evalGreaterUnsigned (lw, lv, rw, rv); break;
|
||||||
|
case LESS_EQUAL_SIGNED :
|
||||||
|
value = evalLessEqualSigned (lw, lv, rw, rv); break;
|
||||||
|
case LESS_EQUAL_UNSIGNED :
|
||||||
|
value = evalLessEqualUnsigned (lw, lv, rw, rv); break;
|
||||||
|
case LESS_SIGNED :
|
||||||
|
value = evalLessSigned (lw, lv, rw, rv); break;
|
||||||
|
case LESS_UNSIGNED :
|
||||||
|
value = evalLessUnsigned (lw, lv, rw, rv); break;
|
||||||
|
case NOT_EQUAL :
|
||||||
|
value = evalNotEqual (lw, lv, rw, rv); break;
|
||||||
|
|
||||||
|
// Logical
|
||||||
|
default:
|
||||||
|
lw = (lv & (lw ? 0xFFFFFFFF : 0x7FFFFFFF)) != 0;
|
||||||
|
rw = (rv & (rw ? 0xFFFFFFFF : 0x7FFFFFFF)) != 0;
|
||||||
|
|
||||||
|
// Evaluate &&
|
||||||
|
case LOGICAL_AND:
|
||||||
|
type = lt; value = lv;
|
||||||
|
if (lw)
|
||||||
|
{ type = rt; value = rv; }
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Evaluate ||
|
||||||
|
case LOGICAL_OR:
|
||||||
|
type = lt; value = lv;
|
||||||
|
if (!lw)
|
||||||
|
{ type = rt; value = rv; }
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Evaluate ^^
|
||||||
|
case LOGICAL_XOR:
|
||||||
|
type = rt; value = rv;
|
||||||
|
if (lw == rw)
|
||||||
|
{ type = WORD; value = 0; }
|
||||||
|
else if (lw)
|
||||||
|
{ type = lt; value = lv; }
|
||||||
|
break;
|
||||||
|
}}
|
||||||
stack[size - 4] = type;
|
stack[size - 4] = type;
|
||||||
stack[size - 3] = ret;
|
stack[size - 3] = value;
|
||||||
return size - 2;
|
return size - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate +
|
|
||||||
private int evalAdd(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return type == WORD ? lw + rw : Float.floatToRawIntBits(lf + rf);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate &
|
|
||||||
private int evalBitwiseAnd(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return type == WORD ? lw & rw : Float.floatToRawIntBits(
|
|
||||||
fixFloat(Float.intBitsToFloat(lw & rw)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate |
|
|
||||||
private int evalBitwiseOr(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return type == WORD ? lw | rw : Float.floatToRawIntBits(
|
|
||||||
fixFloat(Float.intBitsToFloat(lw | rw)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate ^
|
|
||||||
private int evalBitwiseXOr(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return type == WORD ? lw ^ rw : Float.floatToRawIntBits(
|
|
||||||
fixFloat(Float.intBitsToFloat(lw ^ rw)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate /
|
|
||||||
private int evalDivide(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return type == WORD ? rw == 0 ? 0 : lw / rw : rf == 0 ? 0 :
|
|
||||||
Float.floatToRawIntBits(lf / rf);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate ==
|
|
||||||
private int evalEqual(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return (type == WORD ? lw == rw : lf == rf) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate >=
|
|
||||||
private int evalGreaterEqualSigned(int type,
|
|
||||||
int lw, float lf, int rw, float rf) {
|
|
||||||
return (type == WORD ? lw >= rw : (lf >= rf)) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate >=_
|
|
||||||
private int evalGreaterEqualUnsigned(int type,
|
|
||||||
int lw, float lf, int rw, float rf) {
|
|
||||||
return (type == WORD ? Integer.compareUnsigned(lw, rw) >= 0 :
|
|
||||||
(lf >= rf)) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate >
|
|
||||||
private int evalGreaterSigned(int type,int lw,float lf,int rw,float rf) {
|
|
||||||
return (type == WORD ? lw > rw : (lf > rf)) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate >_
|
|
||||||
private int evalGreaterUnsigned(int type,int lw,float lf,int rw,float rf) {
|
|
||||||
return (type == WORD ? Integer.compareUnsigned(lw, rw) > 0 :
|
|
||||||
(lf > rf)) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate <=
|
|
||||||
private int evalLessEqualSigned(int type,
|
|
||||||
int lw, float lf, int rw, float rf) {
|
|
||||||
return (type == WORD ? lw <= rw : (lf <= rf)) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate <=_
|
|
||||||
private int evalLessEqualUnsigned(int type,
|
|
||||||
int lw, float lf, int rw, float rf) {
|
|
||||||
return (type == WORD ? Integer.compareUnsigned(lw, rw) <= 0 :
|
|
||||||
(lf <= rf)) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate <
|
|
||||||
private int evalLessSigned(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return (type == WORD ? lw < rw : (lf < rf)) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate <_
|
|
||||||
private int evalLessUnsigned(int type, int lw, float lf, int rw, float rf){
|
|
||||||
return (type == WORD ? Integer.compareUnsigned(lw, rw) < 0 :
|
|
||||||
(lf < rf)) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate &&
|
|
||||||
private int evalLogicalAnd(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return type == WORD ? lw != 0 ? rw : 0 :
|
|
||||||
Float.floatToRawIntBits(lf != 0 ? rf : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate ||
|
|
||||||
private int evalLogicalOr(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return type == WORD ? lw != 0 ? lw : rw :
|
|
||||||
Float.floatToRawIntBits(lf != 0 ? lf : rf);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate ^^
|
|
||||||
private int evalLogicalXOr(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return type == WORD ? lw!=0 ? rw!=0 ? 0 : lw : rw!=0 ? rw : 0 :
|
|
||||||
Float.floatToRawIntBits(lf!=0 ? rf!=0 ? 0 : lf : rf!=0 ? rf : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate *
|
|
||||||
private int evalMultiply(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return type == WORD ? lw * rw : Float.floatToRawIntBits(lf * rf);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate !=
|
|
||||||
private int evalNotEqual(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return (type == WORD ? lw != rw : lf != rf) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate %
|
|
||||||
private int evalRemainder(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return type == WORD ? rw == 0 ? 0 : lw % rw : rf == 0 ? 0 :
|
|
||||||
Float.floatToRawIntBits(lf % rf);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate <<
|
|
||||||
private int evalShiftLeft(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return type == WORD ? lw << (rw & 31) : Float.floatToRawIntBits(
|
|
||||||
fixFloat(Float.intBitsToFloat(lw << ((int) rf & 31))));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate >>>
|
|
||||||
private int evalShiftRight(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return type == WORD ? lw >>> (rw & 31) : Float.floatToRawIntBits(
|
|
||||||
fixFloat(Float.intBitsToFloat(lw >>> ((int) rf & 31))));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate >>
|
|
||||||
private int evalShiftRightArithmetic(int type,
|
|
||||||
int lw, float lf, int rw, float rf) {
|
|
||||||
return type == WORD ? lw >> (rw & 31) : Float.floatToRawIntBits(
|
|
||||||
fixFloat(Float.intBitsToFloat(lw >> ((int) rf & 31))));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate -
|
|
||||||
private int evalSubtract(int type, int lw, float lf, int rw, float rf) {
|
|
||||||
return type == WORD ? lw - rw : Float.floatToRawIntBits(lf - rf);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate a functional symbol
|
// Evaluate a functional symbol
|
||||||
private int evalSymbol(JavaVUE vue, int id, int[] stack, int size) {
|
private static int evalSymbol(JavaVUE vue, int id, int[] stack, int size) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
if (vue.cpu.stage == CPU.EXCEPTION) switch (id) {
|
if (id == VUE.PC)
|
||||||
case CODE: ret = vue.cpu.exception.code; break;
|
ret = vue.cpu.pc;
|
||||||
}
|
else if (id >= 200)
|
||||||
else switch (id) {
|
ret = vue.cpu.getSystemRegister(id - 200);
|
||||||
|
else if (id >= 100)
|
||||||
|
ret = vue.cpu.program[id - 100];
|
||||||
|
else if (vue.cpu.stage == CPU.EXCEPTION && id == CODE)
|
||||||
|
ret = vue.cpu.exception.code;
|
||||||
|
else if (vue.cpu.stage == CPU.EXECUTE) switch (id) {
|
||||||
case ADDRESS : ret = evalAddress (vue); break;
|
case ADDRESS : ret = evalAddress (vue); break;
|
||||||
case COND : ret = evalCond (vue); break;
|
case COND : ret = evalCond (vue); break;
|
||||||
case DISP : ret = evalDisp (vue); break;
|
case DISP : ret = evalDisp (vue); break;
|
||||||
|
@ -1116,8 +1025,235 @@ public class Breakpoint {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Evaluate a unary operator
|
||||||
|
private static void evalUnary(JavaVUE vue, int id, int[] stack, int size) {
|
||||||
|
int type = stack[size - 2];
|
||||||
|
int value = stack[size - 1];
|
||||||
|
boolean isWord = type == WORD;
|
||||||
|
switch (id) {
|
||||||
|
case BITWISE_NOT: value = evalBitwiseNot(isWord, value);
|
||||||
|
type = WORD ; break;
|
||||||
|
case LOGICAL_NOT: value = evalLogicalNot(isWord, value);
|
||||||
|
type = WORD ; break;
|
||||||
|
case NEGATE : value = evalNegate (isWord, value); break;
|
||||||
|
case CEIL : value = evalCeil (isWord, value); break;
|
||||||
|
case FLOAT : value = evalFloat (isWord, value);
|
||||||
|
type = FLOAT; break;
|
||||||
|
case FLOOR : value = evalFloor (isWord, value); break;
|
||||||
|
case READ_WORD : value = evalReadWord (isWord, value, vue);
|
||||||
|
type = WORD ; break;
|
||||||
|
case ROUND : value = evalRound (isWord, value); break;
|
||||||
|
case TRUNC : value = evalTrunc (isWord, value); break;
|
||||||
|
case WORD : value = evalWord (isWord, value);
|
||||||
|
type = WORD ; break;
|
||||||
|
case XFLOAT : value = evalXFloat (isWord, value);
|
||||||
|
type = FLOAT; break;
|
||||||
|
case XWORD : type = WORD;
|
||||||
|
}
|
||||||
|
stack[size - 2] = type;
|
||||||
|
stack[size - 1] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Binary Methods //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Evaluate +
|
||||||
|
private static int evalAdd(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return leftWord && rightWord ? leftValue + rightValue : asWord(
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) +
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate &
|
||||||
|
private static int evalBitwiseAnd(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return (leftWord ? leftValue : toWord(asFloat(leftValue ))) &
|
||||||
|
(rightWord ? rightValue : toWord(asFloat(rightValue)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate |
|
||||||
|
private static int evalBitwiseOr(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return (leftWord ? leftValue : toWord(asFloat(leftValue ))) |
|
||||||
|
(rightWord ? rightValue : toWord(asFloat(rightValue)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate ^
|
||||||
|
private static int evalBitwiseXOr(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return (leftWord ? leftValue : toWord(asFloat(leftValue ))) ^
|
||||||
|
(rightWord ? rightValue : toWord(asFloat(rightValue)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate /
|
||||||
|
private static int evalDivide(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return (rightWord ? rightValue : rightValue & 0x7FFFFFFF) == 0 ? 0 :
|
||||||
|
leftWord && rightWord ? leftValue / rightValue : asWord(
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) /
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate ==
|
||||||
|
private static int evalEqual(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return (leftWord && rightWord ? leftValue == rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) ==
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate >=
|
||||||
|
private static int evalGreaterEqualSigned(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return (leftWord && rightWord ? leftValue >= rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) >=
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate >=_
|
||||||
|
private static int evalGreaterEqualUnsigned(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return (leftWord && rightWord ?
|
||||||
|
Integer.compareUnsigned(leftValue, rightValue) >= 0 : (
|
||||||
|
(leftWord ? ufloat(leftValue ) : asFloat(leftValue )) >=
|
||||||
|
(rightWord ? ufloat(rightValue) : asFloat(rightValue))
|
||||||
|
)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate >
|
||||||
|
private static int evalGreaterSigned(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return (leftWord && rightWord ? leftValue > rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) >
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate >_
|
||||||
|
private static int evalGreaterUnsigned(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return (leftWord && rightWord ?
|
||||||
|
Integer.compareUnsigned(leftValue, rightValue) > 0 : (
|
||||||
|
(leftWord ? ufloat(leftValue ) : asFloat(leftValue )) >
|
||||||
|
(rightWord ? ufloat(rightValue) : asFloat(rightValue))
|
||||||
|
)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate <=
|
||||||
|
private static int evalLessEqualSigned(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return (leftWord && rightWord ? leftValue <= rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) <=
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate <=_
|
||||||
|
private static int evalLessEqualUnsigned(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return (leftWord && rightWord ?
|
||||||
|
Integer.compareUnsigned(leftValue, rightValue) <= 0 : (
|
||||||
|
(leftWord ? ufloat(leftValue ) : asFloat(leftValue )) <=
|
||||||
|
(rightWord ? ufloat(rightValue) : asFloat(rightValue))
|
||||||
|
)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate <
|
||||||
|
private static int evalLessSigned(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return (leftWord && rightWord ? leftValue < rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) <
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate <_
|
||||||
|
private static int evalLessUnsigned(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return (leftWord && rightWord ?
|
||||||
|
Integer.compareUnsigned(leftValue, rightValue) < 0 : (
|
||||||
|
(leftWord ? ufloat(leftValue ) : asFloat(leftValue )) <
|
||||||
|
(rightWord ? ufloat(rightValue) : asFloat(rightValue))
|
||||||
|
)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate *
|
||||||
|
private static int evalMultiply(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return leftWord && rightWord ? leftValue * rightValue : asWord(
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) *
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate !=
|
||||||
|
private static int evalNotEqual(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return (leftWord && rightWord ? leftValue != rightValue : (
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) !=
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate %
|
||||||
|
private static int evalRemainder(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return (rightWord ? rightValue : rightValue & 0x7FFFFFFF) == 0 ? 0 :
|
||||||
|
leftWord && rightWord ? leftValue % rightValue : asWord(
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) %
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate <<
|
||||||
|
private static int evalShiftLeft(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
leftValue = leftWord ? leftValue : toWord(asFloat(leftValue ));
|
||||||
|
leftValue = (rightWord ? rightValue : toWord(asFloat(rightValue)))&31;
|
||||||
|
return leftValue << rightValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate >>>
|
||||||
|
private static int evalShiftRight(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
leftValue = leftWord ? leftValue : toWord(asFloat(leftValue ));
|
||||||
|
leftValue = (rightWord ? rightValue : toWord(asFloat(rightValue)))&31;
|
||||||
|
return leftValue >>> rightValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate >>
|
||||||
|
private static int evalShiftRightArithmetic(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
leftValue = leftWord ? leftValue : toWord(asFloat(leftValue ));
|
||||||
|
leftValue = (rightWord ? rightValue : toWord(asFloat(rightValue)))&31;
|
||||||
|
return leftValue >> rightValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate -
|
||||||
|
private static int evalSubtract(
|
||||||
|
boolean leftWord, int leftValue, boolean rightWord, int rightValue) {
|
||||||
|
return leftWord && rightWord ? leftValue - rightValue : asWord(
|
||||||
|
(leftWord ? (float) leftValue : asFloat(leftValue )) -
|
||||||
|
(rightWord ? (float) rightValue : asFloat(rightValue))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Symbol Methods //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Evaluate address
|
// Evaluate address
|
||||||
private int evalAddress(JavaVUE vue) {
|
private static int evalAddress(JavaVUE vue) {
|
||||||
if (vue.cpu.inst.format == 6)
|
if (vue.cpu.inst.format == 6)
|
||||||
return vue.cpu.program[vue.cpu.inst.reg1] + vue.cpu.inst.disp;
|
return vue.cpu.program[vue.cpu.inst.reg1] + vue.cpu.inst.disp;
|
||||||
switch (vue.cpu.inst.id) {
|
switch (vue.cpu.inst.id) {
|
||||||
|
@ -1132,7 +1268,7 @@ public class Breakpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate cond
|
// Evaluate cond
|
||||||
private int evalCond(JavaVUE vue) {
|
private static int evalCond(JavaVUE vue) {
|
||||||
switch (vue.cpu.inst.id) {
|
switch (vue.cpu.inst.id) {
|
||||||
case VUE.BCOND: return vue.cpu.inst.cond;
|
case VUE.BCOND: return vue.cpu.inst.cond;
|
||||||
case VUE.SETF : return vue.cpu.inst.imm;
|
case VUE.SETF : return vue.cpu.inst.imm;
|
||||||
|
@ -1141,7 +1277,7 @@ public class Breakpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate disp
|
// Evaluate disp
|
||||||
private int evalDisp(JavaVUE vue) {
|
private static int evalDisp(JavaVUE vue) {
|
||||||
switch (vue.cpu.inst.format) {
|
switch (vue.cpu.inst.format) {
|
||||||
case 3: case 4: case 6: return vue.cpu.inst.disp;
|
case 3: case 4: case 6: return vue.cpu.inst.disp;
|
||||||
}
|
}
|
||||||
|
@ -1149,7 +1285,7 @@ public class Breakpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate imm
|
// Evaluate imm
|
||||||
private int evalImm(JavaVUE vue) {
|
private static int evalImm(JavaVUE vue) {
|
||||||
switch (vue.cpu.inst.format) {
|
switch (vue.cpu.inst.format) {
|
||||||
case 2: case 5: return vue.cpu.inst.imm;
|
case 2: case 5: return vue.cpu.inst.imm;
|
||||||
}
|
}
|
||||||
|
@ -1157,7 +1293,7 @@ public class Breakpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate reg1
|
// Evaluate reg1
|
||||||
private int evalReg1(JavaVUE vue) {
|
private static int evalReg1(JavaVUE vue) {
|
||||||
switch (vue.cpu.inst.format) {
|
switch (vue.cpu.inst.format) {
|
||||||
case 1: case 5: case 6: case 7: return vue.cpu.inst.reg1;
|
case 1: case 5: case 6: case 7: return vue.cpu.inst.reg1;
|
||||||
}
|
}
|
||||||
|
@ -1165,7 +1301,7 @@ public class Breakpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate reg2
|
// Evaluate reg2
|
||||||
private int evalReg2(JavaVUE vue) {
|
private static int evalReg2(JavaVUE vue) {
|
||||||
switch (vue.cpu.inst.format) {
|
switch (vue.cpu.inst.format) {
|
||||||
case 1: case 2: case 5: case 6: case 7: return vue.cpu.inst.reg2;
|
case 1: case 2: case 5: case 6: case 7: return vue.cpu.inst.reg2;
|
||||||
}
|
}
|
||||||
|
@ -1173,7 +1309,7 @@ public class Breakpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate regid
|
// Evaluate regid
|
||||||
private int evalRegId(JavaVUE vue) {
|
private static int evalRegId(JavaVUE vue) {
|
||||||
switch (vue.cpu.inst.id) {
|
switch (vue.cpu.inst.id) {
|
||||||
case VUE.LDSR: case VUE.STSR: return vue.cpu.inst.imm;
|
case VUE.LDSR: case VUE.STSR: return vue.cpu.inst.imm;
|
||||||
}
|
}
|
||||||
|
@ -1181,7 +1317,7 @@ public class Breakpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate subopcode
|
// Evaluate subopcode
|
||||||
private int evalSubopcode(JavaVUE vue) {
|
private static int evalSubopcode(JavaVUE vue) {
|
||||||
switch (vue.cpu.inst.opcode) {
|
switch (vue.cpu.inst.opcode) {
|
||||||
case 0x1F: return vue.cpu.inst.imm;
|
case 0x1F: return vue.cpu.inst.imm;
|
||||||
case 0x3E: return vue.cpu.inst.subopcode;
|
case 0x3E: return vue.cpu.inst.subopcode;
|
||||||
|
@ -1190,110 +1326,75 @@ public class Breakpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate value
|
// Evaluate value
|
||||||
private int evalValue(JavaVUE vue) {
|
private static int evalValue(JavaVUE vue) {
|
||||||
return vue.cpu.inst.format == 6 ? vue.cpu.access.value : 0;
|
return vue.cpu.inst.format == 6 ? vue.cpu.access.value : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate vector
|
// Evaluate vector
|
||||||
private int evalVector(JavaVUE vue) {
|
private static int evalVector(JavaVUE vue) {
|
||||||
return vue.cpu.inst.id == VUE.TRAP ? vue.cpu.inst.imm : 0;
|
return vue.cpu.inst.id == VUE.TRAP ? vue.cpu.inst.imm : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate a unary operator
|
|
||||||
private int evalUnary(JavaVUE vue, int id, int[] stack, int size) {
|
|
||||||
int ret = 0;
|
///////////////////////////////////////////////////////////////////////////
|
||||||
int type = stack[size - 2];
|
// Unary Methods //
|
||||||
int w = stack[size - 1];
|
///////////////////////////////////////////////////////////////////////////
|
||||||
float f = Float.intBitsToFloat(w);
|
|
||||||
switch (id) {
|
|
||||||
case BITWISE_NOT: ret = evalBitwiseNot(type, w, f); break;
|
|
||||||
case LOGICAL_NOT: ret = evalLogicalNot(type, w, f);
|
|
||||||
type = WORD ; break;
|
|
||||||
case NEGATE : ret = evalNegate (type, w, f); break;
|
|
||||||
case CEIL : ret = evalCeil (type, w, f); break;
|
|
||||||
case FLOATOP : ret = evalFloat (type, w, f);
|
|
||||||
type = FLOAT; break;
|
|
||||||
case FLOOR : ret = evalFloor (type, w, f); break;
|
|
||||||
case READ_WORD : ret = evalReadWord (type, w, f, vue);
|
|
||||||
type = WORD ; break;
|
|
||||||
case ROUND : ret = evalRound (type, w, f); break;
|
|
||||||
case TRUNC : ret = evalTrunc (type, w, f); break;
|
|
||||||
case WORDOP : ret = evalWord (type, w, f);
|
|
||||||
type = WORD ; break;
|
|
||||||
case XFLOAT : ret = evalXFloat (type, w, f);
|
|
||||||
type = FLOAT; break;
|
|
||||||
case XWORD : ret = w; type = WORD; break;
|
|
||||||
}
|
|
||||||
stack[size - 2] = type;
|
|
||||||
stack[size - 1] = ret;
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate ~
|
// Evaluate ~
|
||||||
private int evalBitwiseNot(int type, int w, float f) {
|
private static int evalBitwiseNot(boolean isWord, int value) {
|
||||||
return type == WORD ? ~w :
|
return isWord ? ~value : ~toWord(asFloat(value));
|
||||||
Float.floatToRawIntBits(fixFloat(Float.intBitsToFloat(~w)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate !
|
// Evaluate !
|
||||||
private int evalLogicalNot(int type, int w, float f) {
|
private static int evalLogicalNot(boolean isWord, int value) {
|
||||||
return (type == WORD ? w == 0 : f == 0) ? 1 : 0;
|
return (isWord ? value != 0 : (value & 0x7FFFFFFF) != 0) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate -
|
// Evaluate -
|
||||||
private int evalNegate(int type, int w, float f) {
|
private static int evalNegate(boolean isWord, int value) {
|
||||||
return type == WORD ? -w : Float.floatToRawIntBits(-f);
|
return isWord ? -value : asWord(-asFloat(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate ceil
|
// Evaluate ceil
|
||||||
private int evalCeil(int type, int w, float f) {
|
private static int evalCeil(boolean isWord, int value) {
|
||||||
return type == WORD ? w :
|
return isWord ? value : asWord((float) Math.ceil(asFloat(value)));
|
||||||
Float.floatToRawIntBits((float) Math.ceil(f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate float
|
// Evaluate float
|
||||||
private int evalFloat(int type, int w, float f) {
|
private static int evalFloat(boolean isWord, int value) {
|
||||||
return Float.floatToRawIntBits(type == FLOAT ? f : (float) w);
|
return isWord ? asWord((float) value) : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate floor
|
// Evaluate floor
|
||||||
private int evalFloor(int type, int w, float f) {
|
private static int evalFloor(boolean isWord, int value) {
|
||||||
return type == WORD ? w :
|
return isWord ? value : asWord((float) Math.floor(asFloat(value)));
|
||||||
Float.floatToRawIntBits((float) Math.floor(f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate []
|
// Evaluate []
|
||||||
private int evalReadWord(int type, int w, float f, JavaVUE vue) {
|
private static int evalReadWord(boolean isWord, int value, JavaVUE vue) {
|
||||||
if (type == FLOAT) {
|
return vue.read(isWord ? value : toWord(asFloat(value)), VUE.S32);
|
||||||
if (f > 0x7FFFFFFF || f < 0x80000000)
|
|
||||||
return 0;
|
|
||||||
w = (int) f;
|
|
||||||
}
|
|
||||||
return vue.read(w, VUE.S32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate round
|
// Evaluate round
|
||||||
private int evalRound(int type, int w, float f) {
|
private static int evalRound(boolean isWord, int value) {
|
||||||
return type == WORD ? w :
|
return isWord ? value : asWord((float) Math.round(asFloat(value)));
|
||||||
Float.floatToRawIntBits((float) Math.round(f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate trunc
|
// Evaluate trunc
|
||||||
private int evalTrunc(int type, int w, float f) {
|
private static int evalTrunc(boolean isWord, int value) {
|
||||||
return type == WORD ? w : Float.floatToRawIntBits((float)
|
return isWord ? value : asWord((float) (value < 0 ?
|
||||||
(f < 0 ? Math.ceil(f) : Math.floor(f)));
|
Math.ceil(asFloat(value)) : Math.ceil(asFloat(value))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate word
|
// Evaluate word
|
||||||
private int evalWord(int type, int w, float f) {
|
private static int evalWord(boolean isWord, int value) {
|
||||||
return type == WORD ? w :
|
return isWord ? value : toWord(asFloat(value));
|
||||||
f > 0x7FFFFFFF || f < 0x80000000 ? 0 : (int) f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate xfloat
|
// Evaluate xfloat
|
||||||
private int evalXFloat(int type, int w, float f) {
|
private static int evalXFloat(boolean isWord, int value) {
|
||||||
return Float.floatToRawIntBits(type == FLOAT ? f :
|
return isWord ? asWord(asFloat(value)) : value;
|
||||||
fixFloat(Float.intBitsToFloat(w)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <vue.h>
|
#include <vue.h>
|
||||||
#include "vue_NativeVUE.h"
|
#include "vue_NativeVUE.h"
|
||||||
|
@ -21,27 +22,58 @@ static const int TYPE_SIZES[] = { 1, 1, 2, 2, 4 };
|
||||||
// Types //
|
// Types //
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Breakpoint token
|
||||||
|
typedef struct {
|
||||||
|
int32_t type;
|
||||||
|
int32_t value;
|
||||||
|
} TOKEN;
|
||||||
|
|
||||||
|
// Precompiled breakpoint
|
||||||
|
typedef struct {
|
||||||
|
int32_t enabled; // The breakpoint is enabled
|
||||||
|
int32_t numAddresses; // Number of address ranges
|
||||||
|
int32_t numCondition; // Number of tokens in condition
|
||||||
|
int32_t *addresses; // Address ranges
|
||||||
|
TOKEN *condition; // Condition tokens in RPN order
|
||||||
|
} BREAKPOINT;
|
||||||
|
|
||||||
// Core context state type
|
// Core context state type
|
||||||
typedef struct {
|
typedef struct {
|
||||||
VUE vue; /* Context into the generic C library */
|
VUE vue; // Context into the generic C library
|
||||||
|
int32_t numBreakpoints; // Number of breakpoints
|
||||||
|
BREAKPOINT *breakpoints; // Application breakpoints
|
||||||
|
int32_t *stack; // Expression stack for breakpoints
|
||||||
} CORE;
|
} CORE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Macros //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/* Sign-extend a value */
|
||||||
|
#define SIGN_EXTEND(bits, value) \
|
||||||
|
((value) & 1 << (bits - 1) ? (value) | (~(1 << bits) + 1) : (value))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Component Includes //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define NATIVEVUE
|
||||||
|
#include "Breakpoint.c"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Internal Functions //
|
// Internal Functions //
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Determine the field ID of NativeVUE.pointer
|
|
||||||
static jfieldID GetPointerID(JNIEnv *env, jobject vue) {
|
|
||||||
return (*env)->GetFieldID(env,
|
|
||||||
(*env)->GetObjectClass(env, vue), "pointer", "[B");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve the handle to a NativeVUE's core context
|
// Retrieve the handle to a NativeVUE's core context
|
||||||
static CORE* GetCore(JNIEnv *env, jobject vue) {
|
static CORE* GetCore(JNIEnv *env, jobject vue) {
|
||||||
jbyteArray pointer =
|
jbyteArray pointer = (*env)->GetObjectField(env, vue, (*env)->GetFieldID(
|
||||||
(*env)->GetObjectField(env, vue, GetPointerID(env, vue));
|
env, (*env)->GetObjectClass(env, vue), "pointer", "[B"));
|
||||||
jbyte *elems = (*env)->GetByteArrayElements(env, pointer, NULL);
|
jbyte *elems = (*env)->GetByteArrayElements(env, pointer, NULL);
|
||||||
CORE *core = *(CORE **)elems;
|
CORE *core = *(CORE **)elems;
|
||||||
(*env)->ReleaseByteArrayElements(env, pointer, elems, 0);
|
(*env)->ReleaseByteArrayElements(env, pointer, elems, 0);
|
||||||
|
@ -55,10 +87,10 @@ static CORE* GetCore(JNIEnv *env, jobject vue) {
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Native constructor
|
// Native constructor
|
||||||
JNIEXPORT void JNICALL Java_vue_NativeVUE_construct
|
JNIEXPORT jbyteArray JNICALL Java_vue_NativeVUE_construct
|
||||||
(JNIEnv *env, jobject vue) {
|
(JNIEnv *env, jobject vue) {
|
||||||
|
|
||||||
// Produce and initialize s new core context
|
// Produce and initialize a new core context
|
||||||
CORE *core = calloc(sizeof (CORE), 1);
|
CORE *core = calloc(sizeof (CORE), 1);
|
||||||
vueInitialize(&core->vue);
|
vueInitialize(&core->vue);
|
||||||
vueReset(&core->vue);
|
vueReset(&core->vue);
|
||||||
|
@ -68,7 +100,7 @@ JNIEXPORT void JNICALL Java_vue_NativeVUE_construct
|
||||||
jbyte *elems = (*env)->GetByteArrayElements(env, pointer, NULL);
|
jbyte *elems = (*env)->GetByteArrayElements(env, pointer, NULL);
|
||||||
*(CORE **)elems = core;
|
*(CORE **)elems = core;
|
||||||
(*env)->ReleaseByteArrayElements(env, pointer, elems, 0);
|
(*env)->ReleaseByteArrayElements(env, pointer, elems, 0);
|
||||||
(*env)->SetObjectField(env, vue, GetPointerID(env, vue), pointer);
|
return pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release any used resources
|
// Release any used resources
|
||||||
|
|
|
@ -14,7 +14,7 @@ class NativeVUE extends VUE {
|
||||||
|
|
||||||
// Default constructor
|
// Default constructor
|
||||||
NativeVUE() {
|
NativeVUE() {
|
||||||
construct();
|
pointer = construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,6 +86,6 @@ class NativeVUE extends VUE {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Native constructor
|
// Native constructor
|
||||||
private native void construct();
|
private native byte[] construct();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue