From 11890026db9f4a2b3978284fa493d383020015a9 Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 19 May 2013 23:34:42 +0100 Subject: [PATCH] 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 --- mach/vc4/as/mach3.c | 4 ++-- mach/vc4/as/mach5.c | 31 +++++++++++++++++-------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/mach/vc4/as/mach3.c b/mach/vc4/as/mach3.c index aba49dca2..f47c024dd 100644 --- a/mach/vc4/as/mach3.c +++ b/mach/vc4/as/mach3.c @@ -133,8 +133,8 @@ 0, OP_MISCL, B16(11000100,10000000), "divs", 0, OP_MISCL, B16(11000100,11100000), "divu", -0, OP_STACK, B16(00000010,00000000), "push", -0, OP_STACK, B16(00000010,10000000), "pop", +0, OP_STACK, B16(00000010,10000000), "push", +0, OP_STACK, B16(00000010,00000000), "pop", 0, OP_MEM, B8(00000000), "ld", 0, OP_MEM, B8(00000001), "st", diff --git a/mach/vc4/as/mach5.c b/mach/vc4/as/mach5.c index 056a8b7aa..6314ed1f3 100644 --- a/mach/vc4/as/mach5.c +++ b/mach/vc4/as/mach5.c @@ -13,7 +13,7 @@ void alu_instr_reg(quad op, int cc, int rd, int ra, int rb) { /* 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)); return; @@ -32,7 +32,7 @@ void alu_instr_lit(quad op, int cc, int rd, int ra, quad value) /* 16 bit short form? */ if ((cc == ALWAYS) && !(op & 1) && (value <= 0x1f) && (ra == rd) && - !(ra & 0x10)) + (ra < 0x10)) { emit2(B16(01100000,00000000) | (op<<8) | (value<<4) | (rd<<0)); 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) { int b; + int m; switch (loreg) { @@ -172,15 +173,13 @@ void stack_instr(quad opcode, int loreg, int hireg, int extrareg) case 26: /* lr */ extrareg = 26; - hireg = 31; - loreg = 0; + hireg = loreg = -1; b = 0; break; case 31: /* pc */ extrareg = 31; - hireg = 31; - loreg = 0; + hireg = loreg = -1; b = 0; break; @@ -189,23 +188,27 @@ void stack_instr(quad opcode, int loreg, int hireg, int extrareg) } if (opcode & 0x0080) - { - /* Pop */ - if (extrareg == 26) - serror("cannot pop lr"); - } - else { /* Push */ if (extrareg == 31) serror("cannot push pc"); } + else + { + /* Pop */ + if (extrareg == 26) + serror("cannot pop lr"); + } if (hireg < loreg) serror("invalid register range"); - emit2(opcode | (b<<5) | (hireg<<0) | - ((extrareg != -1) ? 0x0100 : 0)); + if (hireg == -1) + 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). */ -- 2.34.1