Add register offset and postincrement memory operations.
authorDavid Given <dg@cowlark.com>
Sun, 19 May 2013 11:39:35 +0000 (12:39 +0100)
committerDavid Given <dg@cowlark.com>
Sun, 19 May 2013 11:39:35 +0000 (12:39 +0100)
--HG--
branch : dtrg-videocore

mach/vc4/as/mach1.c
mach/vc4/as/mach4.c
mach/vc4/as/mach5.c
mach/vc4/test/opcodes.s

index bfb298f..25d5034 100644 (file)
@@ -9,21 +9,12 @@
 
 #define ALWAYS 14
 
-extern void alu_instr_reg(quad opcode, quad cc, quad rd,
-       quad ra, quad rb);
-
-extern void alu_instr_lit(quad opcode, quad cc, quad rd,
-       quad ra, quad value);
-
-extern void misc_instr_reg(quad opcode, quad cc, quad rd,
-       quad ra, quad rb);
-
-extern void misc_instr_lit(quad opcode, quad cc, quad rd,
-       quad ra, quad value);
-
-extern void branch_instr(quad bl, quad cc, struct expr_t* expr);
-
-extern void stack_instr(quad opcode, quad loreg, quad hireg,
-       quad extrareg);
-
-extern void mem_instr(quad opcode, quad cc, quad rd, long offset, quad rs);
+extern void alu_instr_reg(quad opcode, int cc, int rd, int ra, int rb);
+extern void alu_instr_lit(quad opcode, int cc, int rd, int ra, quad value);
+extern void misc_instr_reg(quad opcode, int cc, int rd, int ra, int rb);
+extern void misc_instr_lit(quad opcode, int cc, int rd, int ra, quad value);
+extern void branch_instr(int bl, int cc, struct expr_t* expr);
+extern void stack_instr(quad opcode, int loreg, int hireg, int extrareg);
+extern void mem_instr(quad opcode, int cc, int rd, long offset, int rs);
+extern void mem_offset_instr(quad opcode, int cc, int rd, int qa, int rb);
+extern void mem_postincr_instr(quad opcode, int cc, int rd, int rs);
index 7bd1838..f614825 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 operation
-       : OP                                              { emit2($1); }
+       : OP                                   { emit2($1); }
 
        | OP_BRANCH GPR                        { emit2($1 | ($2<<0)); }
        | OP_BRANCH expr                       { branch_instr($1, ALWAYS, &$2); }
@@ -47,10 +47,10 @@ operation
        | OP_MEM GPR ',' absexp '(' GPR ')'    { mem_instr($1, ALWAYS, $2, $4, $6); }
        | OP_MEM CC GPR ',' absexp '(' GPR ')' { mem_instr($1, $2, $3, $5, $7); }
 
-    | OP_MEM GPR ',' '(' GPR ',' GPR ')'
-    | OP_MEM CC GPR ',' '(' GPR ',' GPR ')'
+    | OP_MEM GPR ',' '(' GPR ',' GPR ')'   { mem_offset_instr($1, ALWAYS, $2, $5, $7); }
+    | OP_MEM CC GPR ',' '(' GPR ',' GPR ')' { mem_offset_instr($1, $2, $3, $6, $8); }
 
-    | OP_MEM GPR ',' '(' GPR ')' '+' '+'
-    | OP_MEM CC GPR ',' '(' GPR ')' '+' '+'
+    | OP_MEM GPR ',' '(' GPR ')' '+' '+'   { mem_postincr_instr($1, ALWAYS, $2, $5); }
+    | OP_MEM CC GPR ',' '(' GPR ')' '+' '+' { mem_postincr_instr($1, $2, $3, $6); }
        ;
 
index 32d7507..0d68c8f 100644 (file)
@@ -9,7 +9,7 @@
 
 /* Assemble an ALU instruction where rb is a register. */
 
-void alu_instr_reg(quad op, quad cc, quad rd, quad ra, quad rb)
+void alu_instr_reg(quad op, int cc, int rd, int ra, int rb)
 {
        /* Can we use short form? */
 
@@ -27,7 +27,7 @@ void alu_instr_reg(quad op, quad cc, quad rd, quad ra, quad rb)
 
 /* Assemble an ALU instruction where rb is a literal. */
 
-void alu_instr_lit(quad op, quad cc, quad rd, quad ra, quad value)
+void alu_instr_lit(quad op, int cc, int rd, int ra, quad value)
 {
        /* 16 bit short form? */
 
@@ -68,7 +68,7 @@ void alu_instr_lit(quad op, quad cc, quad rd, quad ra, quad value)
 
 /* Miscellaneous instructions with three registers and a cc. */
 
-void misc_instr_reg(quad op, quad cc, quad rd, quad ra, quad rb)
+void misc_instr_reg(quad op, int cc, int rd, int ra, int rb)
 {
        emit2(op | (rd<<0));
        emit2(B16(00000000,00000000) | (ra<<11) | (cc<<7) | (rb<<0));
@@ -76,7 +76,7 @@ void misc_instr_reg(quad op, quad cc, quad rd, quad ra, quad rb)
 
 /* Miscellaneous instructions with two registers, a literal, and a cc. */
 
-void misc_instr_lit(quad op, quad cc, quad rd, quad ra, quad value)
+void misc_instr_lit(quad op, int cc, int rd, int ra, quad value)
 {
     if (value < 0x1f)
         serror("only constants from 0..31 can be used here");
@@ -88,7 +88,7 @@ void misc_instr_lit(quad op, quad cc, quad rd, quad ra, quad value)
 /* Assemble a branch instruction. This may be a near branch into this
  * object file, or a far branch which requires a fixup. */
 
-void branch_instr(quad bl, quad cc, struct expr_t* expr)
+void branch_instr(int bl, int cc, struct expr_t* expr)
 {
        quad type = expr->typ & S_TYP;
 
@@ -159,9 +159,9 @@ void branch_instr(quad bl, quad cc, struct expr_t* expr)
 
 /* Push/pop. */
 
-void stack_instr(quad opcode, quad loreg, quad hireg, quad extrareg)
+void stack_instr(quad opcode, int loreg, int hireg, int extrareg)
 {
-    quad b;
+    int b;
 
     switch (loreg)
     {
@@ -210,7 +210,7 @@ void stack_instr(quad opcode, quad loreg, quad hireg, quad extrareg)
 
 /* Memory operations where the offset is a fixed value (including zero). */
 
-void mem_instr(quad opcode, quad cc, quad rd, long offset, quad rs)
+void mem_instr(quad opcode, int cc, int rd, long offset, int rs)
 {
        quad uoffset = (quad) offset;
        int multiple4 = !(offset & 3);
@@ -310,3 +310,19 @@ void mem_instr(quad opcode, quad cc, quad rd, long offset, quad rs)
        serror("invalid load/store instruction");
 }
 
+/* Memory operations where the destination address is a sum of two
+ * registers. */
+
+void mem_offset_instr(quad opcode, int cc, int rd, int ra, int rb)
+{
+    emit2(B16(10100000,00000000) | (opcode<<5) | (rd<<0));
+    emit2(B16(00000000,00000000) | (ra<<11) | (cc<<7) | (rb<<0));
+}
+
+/* Memory operations with postincrement. */
+
+void mem_postincr_instr(quad opcode, int cc, int rd, int rs)
+{
+    emit2(B16(10100101,00000000) | (opcode<<5) | (rd<<0));
+    emit2(B16(00000000,00000000) | (rs<<11) | (cc<<7));
+}
index 2f9c1c7..ddc6b17 100644 (file)
@@ -333,3 +333,14 @@ forward:
        st.f r0, (r1)
        ld.f r0, 8 (r1)
        st.f r0, 8 (r1)
+
+       ld r0, (r1, r2)
+       st r0, (r1, r2)
+       ld.f r0, (pc, pc)
+       st.f r0, (pc, pc)
+
+       ld r0, (r1)++
+       st r0, (r1)++
+       ld.f pc, (pc)++
+       st.f pc, (pc)++
+