#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);
*/
operation
- : OP { emit2($1); }
+ : OP { emit2($1); }
| OP_BRANCH GPR { emit2($1 | ($2<<0)); }
| OP_BRANCH expr { branch_instr($1, ALWAYS, &$2); }
| 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); }
;
/* 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? */
/* 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? */
/* 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));
/* 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");
/* 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;
/* 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)
{
/* 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);
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));
+}
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)++
+