Permalink
Browse files

pfpuasm: auto-NOP, pass all regs, and some syntax corrections

A number of small improvements:

- VECTOUT doesn't need a destination register (use 0)
- QUAKE is unary, not binary
- option -a to automatically fill the latency slots with NOP
  (without caring about efficiency)
- all registers referenced (read or write) are listed
  • Loading branch information...
1 parent 6e3e917 commit 539486be673605cd8adc2f8b11473568fdc57eb7 @wpwrak wpwrak committed Jan 15, 2012
Showing with 79 additions and 32 deletions.
  1. +47 −29 tools/asm/asm.y
  2. +30 −3 tools/asm/pfpuasm.c
  3. +2 −0 tools/asm/pfpuasm.h
View
@@ -27,14 +27,24 @@
static void emit(int opcode, int opa, int opb, int dest, int latency)
{
- *pc++ |= opcode << OPCODE_SHIFT | opb << OPB_SHIFT | opa << OPA_SHIFT;
+ *pc |= opcode << OPCODE_SHIFT | opb << OPB_SHIFT | opa << OPA_SHIFT;
- if (dest <= 0)
+ if (dest <= 0) {
+ pc++;
return;
-
- if (pc[latency-1] & (DEST_MASK << DEST_SHIFT))
- yyerror("destination conflict");
- pc[latency-1] |= dest << DEST_SHIFT;
+ }
+
+ if (auto_nop) {
+ pc += latency;
+ if (*pc & (DEST_MASK << DEST_SHIFT))
+ yyerror("destination conflict");
+ *pc |= dest << DEST_SHIFT;
+ pc++;
+ } else {
+ if (pc[latency-1] & (DEST_MASK << DEST_SHIFT))
+ yyerror("destination conflict");
+ pc[latency-1] |= dest << DEST_SHIFT;
+ }
}
%}
@@ -56,21 +66,20 @@ static void emit(int opcode, int opa, int opb, int dest, int latency)
%token <reg> REG
%type <i> value
+%type <reg> reg
%%
all:
- regs ops;
+ initials ops;
-regs:
- | reg regs;
+initials:
+ | initial initials;
-reg:
+initial:
REG '=' value
{
regs[$1] = $3;
- if ($1 > max_reg)
- max_reg = $1;
}
;
@@ -93,64 +102,73 @@ op:
{
emit(PFPU_OPCODE_NOP, 0, 0, 0, -1);
}
- | TOK_FADD REG ',' REG ARROW REG
+ | TOK_FADD reg ',' reg ARROW reg
{
BINARY(FADD, $2, $4, $6);
}
- | TOK_FSUB REG ',' REG ARROW REG
+ | TOK_FSUB reg ',' reg ARROW reg
{
BINARY(FSUB, $2, $4, $6);
}
- | TOK_FMUL REG ',' REG ARROW REG
+ | TOK_FMUL reg ',' reg ARROW reg
{
BINARY(FMUL, $2, $4, $6);
}
- | TOK_FABS REG ARROW REG
+ | TOK_FABS reg ARROW reg
{
UNARY(FABS, $2, $4);
}
- | TOK_F2I REG ARROW REG
+ | TOK_F2I reg ARROW reg
{
UNARY(F2I, $2, $4);
}
- | TOK_I2F REG ARROW REG
+ | TOK_I2F reg ARROW reg
{
UNARY(I2F, $2, $4);
}
- | TOK_VECTOUT REG ',' REG ARROW REG
+ | TOK_VECTOUT reg ',' reg
{
- BINARY(VECTOUT, $2, $4, $6);
+ BINARY(VECTOUT, $2, $4, 0);
}
- | TOK_SIN REG ARROW REG
+ | TOK_SIN reg ARROW reg
{
UNARY(SIN, $2, $4);
}
- | TOK_COS REG ARROW REG
+ | TOK_COS reg ARROW reg
{
UNARY(COS, $2, $4);
}
- | TOK_ABOVE REG ',' REG ARROW REG
+ | TOK_ABOVE reg ',' reg ARROW REG
{
BINARY(ABOVE, $2, $4, $6);
}
- | TOK_EQUAL REG ',' REG ARROW REG
+ | TOK_EQUAL reg ',' reg ARROW reg
{
BINARY(EQUAL, $2, $4, $6);
}
- | TOK_COPY REG ARROW REG
+ | TOK_COPY reg ARROW reg
{
UNARY(COPY, $2, $4);
}
- | TOK_IF REG ',' REG ARROW REG
+ | TOK_IF reg ',' reg ARROW reg
{
BINARY(IF, $2, $4, $6);
}
- | TOK_TSIGN REG ',' REG ARROW REG
+ | TOK_TSIGN reg ',' reg ARROW reg
{
BINARY(TSIGN, $2, $4, $6);
}
- | TOK_QUAKE REG ',' REG ARROW REG
+ | TOK_QUAKE reg ARROW reg
+ {
+ UNARY(QUAKE, $2, $4);
+ }
+ ;
+
+reg:
+ REG
{
- BINARY(QUAKE, $2, $4, $6);
+ $$ = $1;
+ if ($1 > max_reg)
+ max_reg = $1;
}
;
View
@@ -13,6 +13,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
+#include <string.h>
#include <signal.h>
#include "hw/pfpu.h"
@@ -29,6 +30,8 @@ uint32_t *pc = prog;
uint32_t regs[PFPU_REG_COUNT];
int max_reg = 0;
+int auto_nop = 0;
+
int yyparse(void);
@@ -43,10 +46,18 @@ static void kill_cpp(void)
}
-static void cpp(char *const *argv)
+static void cpp(int n_args, char *const *args)
{
+ char **argv;
int fds[2];
+ argv = malloc((n_args+2)*sizeof(const char *));
+ if (!argv) {
+ perror("malloc");
+ exit(1);
+ }
+ argv[0] = CPP;
+ memcpy(argv+1, args, sizeof(const char *)*(n_args+1));
if (pipe(fds) < 0) {
perror("pipe");
exit(1);
@@ -104,16 +115,32 @@ static struct attr {
ATTR(COPY, 2),
ATTR(IF, 2),
ATTR(TSIGN, 2),
- ATTR(QUAKE, 2),
+ ATTR(QUAKE, 1),
};
+static void usage(const char *name)
+{
+ fprintf(stderr, "usage: %s [-a] [cpp_options] [file]\n", name);
+ exit(1);
+}
+
+
int main(int argc, char *const *argv)
{
const uint32_t *p;
const uint32_t *r;
+ int c;
- cpp(argv);
+ while ((c = getopt(argc, argv, "a")) != EOF)
+ switch (c) {
+ case 'a':
+ auto_nop = 1;
+ break;
+ default:
+ usage(*argv);
+ }
+ cpp(argc-optind, argv+optind);
(void) yyparse();
for (r = regs+PFPU_SPREG_COUNT; r <= regs+max_reg; r++)
View
@@ -44,6 +44,8 @@ extern uint32_t *pc;
extern uint32_t regs[PFPU_REG_COUNT];
extern int max_reg;
+extern int auto_nop;
+
union u_f2i {
float f;

0 comments on commit 539486b

Please sign in to comment.