Skip to content

Commit

Permalink
add windowcheck
Browse files Browse the repository at this point in the history
  • Loading branch information
imbillow committed Dec 6, 2024
1 parent 2eddfa6 commit ad02e02
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 31 deletions.
127 changes: 109 additions & 18 deletions librz/arch/isa/xtensa/xtensa_il.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,48 @@ static RzILOpPure *reg_field_set(const RegFieldTbl *tbl, ut32 field, RzILOpPure
return NULL;
}

static RzILOpPure *reg_field_get(const RegFieldTbl *tbl, ut32 field, RzILOpPure *orig) {
for (size_t i = 0; i < tbl->size; ++i) {
const RegField *f = tbl->tbl + i;
if (field == f->field) {
return tbl->width == 32
? EXTRACT32(orig, U32(f->offset), U32(f->width))
: EXTRACT64(orig, U32(f->offset), U32(f->width));
}
}
rz_warn_if_reached();
return NULL;
}

#define PS_field_set(F, V) SETG("ps", reg_field_set(&ps_field_tbl, (F), VARG("ps"), (V)))
#define PS_field_get(F) reg_field_get(&ps_field_tbl, (F), VARG("ps"))
#define PS_EXCM_CLEAR PS_field_set(PS_EXCM, U32(0))

static RzILOpEffect *ARi_set(RzILOpPure *i, RzILOpPure *v) {
return BRANCH(
ULT(i, U32(16)),
BRANCH(EQ(DUP(i), U32(15)), SETG("a15", v),
BRANCH(EQ(DUP(i), U32(14)), SETG("a14", DUP(v)),
BRANCH(EQ(DUP(i), U32(13)), SETG("a13", DUP(v)),
BRANCH(EQ(DUP(i), U32(12)), SETG("a12", DUP(v)),
BRANCH(EQ(DUP(i), U32(11)), SETG("a11", DUP(v)),
BRANCH(EQ(DUP(i), U32(10)), SETG("a10", DUP(v)),
BRANCH(EQ(DUP(i), U32(9)), SETG("a9", DUP(v)),
BRANCH(EQ(DUP(i), U32(8)), SETG("a8", DUP(v)),
BRANCH(EQ(DUP(i), U32(7)), SETG("a7", DUP(v)),
BRANCH(EQ(DUP(i), U32(6)), SETG("a6", DUP(v)),
BRANCH(EQ(DUP(i), U32(5)), SETG("a5", DUP(v)),
BRANCH(EQ(DUP(i), U32(4)), SETG("a4", DUP(v)),
BRANCH(EQ(DUP(i), U32(3)), SETG("a3", DUP(v)),
BRANCH(EQ(DUP(i), U32(2)), SETG("a2", DUP(v)),
BRANCH(EQ(DUP(i), U32(1)), SETG("a1", DUP(v)),
BRANCH(EQ(DUP(i), U32(0)), SETG("a0", DUP(v)),
NOP() // Error: Invalid register index
)))))))))))))))),
NOP() // Error: Register index out of range
);
}

static RzAnalysisLiftedILOp op_abs(XtensaContext *ctx) {
return SETG(REGN(0), ABS(IREG(1)));
}
Expand Down Expand Up @@ -377,7 +419,48 @@ static RzAnalysisLiftedILOp op_bltz(XtensaContext *ctx) {
NOP());
}

// Fixme: break
/**
*
* procedure WindowCheck (wr, ws, wt)
* n ← if (wr ≠ 2'b00 or ws ≠ 2'b00 or wt ≠ 2'b00)
* and WindowStartWindowBase+1 then 2’b01
* else if (wr1 or ws1 or wt1)
* and WindowStartWindowBase+2 then 2’b10
* else if (wr = 2'b11 or ws = 2'b11 or wt = 2'b11)
* and WindowStartWindowBase+3 then 2’b11
* else 2’b00
* if CWOE = 1 and n ≠ 2’b00 then
* PS.OWB ← WindowBase
* m ← WindowBase + (2'b00ǁn)
* PS.EXCM ← 1
* EPC[1] ← PC
* nextPC ← if WindowStartm+1 then WindowOverflow4
* else if WindowStartm+2 then WindowOverflow8
* else WindowOverflow12
* WindowBase ← m
* endif
* endprocedure WindowCheck
*/
static RzILOpEffect *WindowCheck(XtensaContext *ctx, RzILOpPure *wr, RzILOpPure *ws, RzILOpPure *wt) {
// TODO: it's not clear what the WindowStartWindowBase+1 means
return SEQ3(
SETL("cwoe", ITE(NON_ZERO(PS_field_get(PS_EXCM)), U32(0), PS_field_get(PS_WOE))),
SETL("n",
ITE(AND(OR(NE(wr, U32(0)), OR(NE(ws, U32(0)), NE(wt, U32(0)))), NE(VARG("windowstart"), U32(0))), U32(1),
ITE(AND(OR(NE(DUP(wr), U32(0)), OR(NE(DUP(ws), U32(0)), NE(DUP(wt), U32(0)))), NE(VARG("windowstart"), U32(1))), U32(2),
ITE(AND(OR(EQ(DUP(wr), U32(3)), OR(EQ(DUP(ws), U32(3)), EQ(DUP(wt), U32(3)))), NE(VARG("windowstart"), U32(2))), U32(3), U32(0))))),
BRANCH(
AND(EQ(VARL("cwoe"), U32(1)), NE(VARL("n"), U32(0))),
SEQ6(
PS_field_set(PS_OWB, VARG("windowbase")),
SETL("m", ADD(VARG("windowbase"), VARL("n"))),
PS_field_set(PS_EXCM, U32(1)),
SETG("epc1", U32(PC)),
SETG("windowbase", VARL("m")),
SETL("nextPC", ITE(EQ(VARG("windowstart"), U32(0)), U32(1), ITE(EQ(VARG("windowstart"), U32(1)), U32(2), U32(3))))),
NOP()));
}

static RzAnalysisLiftedILOp op_break(XtensaContext *ctx) {
return NOP();
}
Expand All @@ -388,23 +471,26 @@ static RzAnalysisLiftedILOp op_call0(XtensaContext *ctx) {
JMP(U32(PC + IMM(0))));
}

// Fixme: WindowCheck
static RzAnalysisLiftedILOp op_call4(XtensaContext *ctx) {
return SEQ2(
return SEQ4(
WindowCheck(ctx, U32(0), U32(0), U32(1)),
PS_field_set(PS_CALLINC, U32(1)),
SETG("a4", U32(0x40000000 | (nextPC & 0x3fffffff))),
JMP(U32(PC + IMM(0))));
}

// Fixme: WindowCheck
static RzAnalysisLiftedILOp op_call8(XtensaContext *ctx) {
return SEQ2(
return SEQ4(
WindowCheck(ctx, U32(0), U32(0), U32(2)),
PS_field_set(PS_CALLINC, U32(2)),
SETG("a8", U32(0x80000000 | (nextPC & 0x3fffffff))),
JMP(U32(PC + IMM(0))));
}

// Fixme: WindowCheck
static RzAnalysisLiftedILOp op_call12(XtensaContext *ctx) {
return SEQ2(
return SEQ4(
WindowCheck(ctx, U32(0), U32(0), U32(3)),
PS_field_set(PS_CALLINC, U32(3)),
SETG("a12", U32(0xc0000000 | (nextPC & 0x3fffffff))),
JMP(U32(PC + IMM(0))));
}
Expand All @@ -416,25 +502,28 @@ static RzAnalysisLiftedILOp op_callx0(XtensaContext *ctx) {
JMP(VARL("next")));
}

// Fixme: WindowCheck
static RzAnalysisLiftedILOp op_callx4(XtensaContext *ctx) {
return SEQ3(
return SEQ5(
WindowCheck(ctx, U32(0), U32(0), U32(1)),
PS_field_set(PS_CALLINC, U32(1)),
SETL("next", IREG(0)),
SETG("a4", U32(0x1 << 29 | (nextPC & 0x3fffffff))),
JMP(VARL("next")));
}

// Fixme: WindowCheck
static RzAnalysisLiftedILOp op_callx8(XtensaContext *ctx) {
return SEQ3(
return SEQ5(
WindowCheck(ctx, U32(0), U32(0), U32(2)),
PS_field_set(PS_CALLINC, U32(2)),
SETL("next", IREG(0)),
SETG("a8", U32(0x2 << 29 | (nextPC & 0x3fffffff))),
JMP(VARL("next")));
}

// Fixme: WindowCheck
static RzAnalysisLiftedILOp op_callx12(XtensaContext *ctx) {
return SEQ3(
return SEQ5(
WindowCheck(ctx, U32(0), U32(0), U32(3)),
PS_field_set(PS_CALLINC, U32(3)),
SETL("next", IREG(0)),
SETG("a12", U32(0x3 << 29 | (nextPC & 0x3fffffff))),
JMP(VARL("next")));
Expand Down Expand Up @@ -508,9 +597,14 @@ static RzAnalysisLiftedILOp op_dsync(XtensaContext *ctx) {
return NOP();
}

// TODO: windowcheck
static RzAnalysisLiftedILOp op_entry(XtensaContext *ctx) {
return NOP();
return SEQ2(
WindowCheck(ctx, U32(0), PS_field_get(PS_CALLINC), U32(0)),
BRANCH(OR(UGT(IREG(0), U32(3)), OR(IS_ZERO(PS_field_get(PS_WOE)), EQ(PS_field_get(PS_EXCM), U32(1)))),
NOP(),
SEQ3(ARi_set(PS_field_get(PS_CALLINC), SUB(IREG(0), U32(IMM(1)))),
SETG("windowbase", ADD(VARG("windowbase"), PS_field_get(PS_CALLINC))),
SETG("windowstart", U32(1)))));
}

static RzAnalysisLiftedILOp op_esync(XtensaContext *ctx) {
Expand Down Expand Up @@ -1012,9 +1106,6 @@ static RzAnalysisLiftedILOp op_rfde(XtensaContext *ctx) {
return JMP(ITE(VARG("ndepc"), VARG("depc"), IEPC(1)));
}

#define PS_field_set(F, V) SETG("ps", reg_field_set(&ps_field_tbl, (F), VARG("ps"), (V)))
#define PS_EXCM_CLEAR PS_field_set(PS_EXCM, U32(0))

static RzAnalysisLiftedILOp op_rfe(XtensaContext *ctx) {
return SEQ2(
PS_EXCM_CLEAR,
Expand Down
Loading

0 comments on commit ad02e02

Please sign in to comment.