Push/pop are the right way round. Don't corrup short-form ALU instructions. Correct encoding of push/pop register ranges.
--HG-- branch : dtrg-videocore
This commit is contained in:
parent
76ba0bf6b3
commit
11890026db
2 changed files with 19 additions and 16 deletions
|
@ -133,8 +133,8 @@
|
||||||
0, OP_MISCL, B16(11000100,10000000), "divs",
|
0, OP_MISCL, B16(11000100,10000000), "divs",
|
||||||
0, OP_MISCL, B16(11000100,11100000), "divu",
|
0, OP_MISCL, B16(11000100,11100000), "divu",
|
||||||
|
|
||||||
0, OP_STACK, B16(00000010,00000000), "push",
|
0, OP_STACK, B16(00000010,10000000), "push",
|
||||||
0, OP_STACK, B16(00000010,10000000), "pop",
|
0, OP_STACK, B16(00000010,00000000), "pop",
|
||||||
|
|
||||||
0, OP_MEM, B8(00000000), "ld",
|
0, OP_MEM, B8(00000000), "ld",
|
||||||
0, OP_MEM, B8(00000001), "st",
|
0, OP_MEM, B8(00000001), "st",
|
||||||
|
|
|
@ -13,7 +13,7 @@ void alu_instr_reg(quad op, int cc, int rd, int ra, int rb)
|
||||||
{
|
{
|
||||||
/* Can we use short form? */
|
/* Can we use short form? */
|
||||||
|
|
||||||
if ((cc == ALWAYS) && (ra == rd))
|
if ((cc == ALWAYS) && (ra == rd) && (ra < 0x10) && (rb < 0x10))
|
||||||
{
|
{
|
||||||
emit2(B16(01000000,00000000) | (op<<8) | (rb<<4) | (rd<<0));
|
emit2(B16(01000000,00000000) | (op<<8) | (rb<<4) | (rd<<0));
|
||||||
return;
|
return;
|
||||||
|
@ -32,7 +32,7 @@ void alu_instr_lit(quad op, int cc, int rd, int ra, quad value)
|
||||||
/* 16 bit short form? */
|
/* 16 bit short form? */
|
||||||
|
|
||||||
if ((cc == ALWAYS) && !(op & 1) && (value <= 0x1f) && (ra == rd) &&
|
if ((cc == ALWAYS) && !(op & 1) && (value <= 0x1f) && (ra == rd) &&
|
||||||
!(ra & 0x10))
|
(ra < 0x10))
|
||||||
{
|
{
|
||||||
emit2(B16(01100000,00000000) | (op<<8) | (value<<4) | (rd<<0));
|
emit2(B16(01100000,00000000) | (op<<8) | (value<<4) | (rd<<0));
|
||||||
return;
|
return;
|
||||||
|
@ -162,6 +162,7 @@ void branch_instr(int bl, int cc, struct expr_t* expr)
|
||||||
void stack_instr(quad opcode, int loreg, int hireg, int extrareg)
|
void stack_instr(quad opcode, int loreg, int hireg, int extrareg)
|
||||||
{
|
{
|
||||||
int b;
|
int b;
|
||||||
|
int m;
|
||||||
|
|
||||||
switch (loreg)
|
switch (loreg)
|
||||||
{
|
{
|
||||||
|
@ -172,15 +173,13 @@ void stack_instr(quad opcode, int loreg, int hireg, int extrareg)
|
||||||
|
|
||||||
case 26: /* lr */
|
case 26: /* lr */
|
||||||
extrareg = 26;
|
extrareg = 26;
|
||||||
hireg = 31;
|
hireg = loreg = -1;
|
||||||
loreg = 0;
|
|
||||||
b = 0;
|
b = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 31: /* pc */
|
case 31: /* pc */
|
||||||
extrareg = 31;
|
extrareg = 31;
|
||||||
hireg = 31;
|
hireg = loreg = -1;
|
||||||
loreg = 0;
|
|
||||||
b = 0;
|
b = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -189,23 +188,27 @@ void stack_instr(quad opcode, int loreg, int hireg, int extrareg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opcode & 0x0080)
|
if (opcode & 0x0080)
|
||||||
{
|
|
||||||
/* Pop */
|
|
||||||
if (extrareg == 26)
|
|
||||||
serror("cannot pop lr");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* Push */
|
/* Push */
|
||||||
if (extrareg == 31)
|
if (extrareg == 31)
|
||||||
serror("cannot push pc");
|
serror("cannot push pc");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Pop */
|
||||||
|
if (extrareg == 26)
|
||||||
|
serror("cannot pop lr");
|
||||||
|
}
|
||||||
|
|
||||||
if (hireg < loreg)
|
if (hireg < loreg)
|
||||||
serror("invalid register range");
|
serror("invalid register range");
|
||||||
|
|
||||||
emit2(opcode | (b<<5) | (hireg<<0) |
|
if (hireg == -1)
|
||||||
((extrareg != -1) ? 0x0100 : 0));
|
m = 31;
|
||||||
|
else
|
||||||
|
m = hireg - loreg;
|
||||||
|
|
||||||
|
emit2(opcode | (b<<5) | (m<<0) | ((extrareg != -1) ? 0x0100 : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Memory operations where the offset is a fixed value (including zero). */
|
/* Memory operations where the offset is a fixed value (including zero). */
|
||||||
|
|
Loading…
Reference in a new issue