pcm: Add support for eq operation
authorPaul Kocialkowski <contact@paulk.fr>
Fri, 3 Mar 2017 16:42:07 +0000 (17:42 +0100)
committerPaul Kocialkowski <contact@paulk.fr>
Fri, 3 Mar 2017 16:42:07 +0000 (17:42 +0100)
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
pcm/pcm.c
pcm/pcm.h

index 689881e..7fef8f2 100644 (file)
--- a/pcm/pcm.c
+++ b/pcm/pcm.c
@@ -270,6 +270,70 @@ static int pcm_op_dummy_disasm(struct pcm_op_desc *desc, unsigned int *arguments
        return 0;
 }
 
+static int pcm_op_eq_asm(struct pcm_op_desc *desc, char *arguments[], unsigned int count)
+{
+       unsigned int value;
+       unsigned int reg_dst;
+       unsigned int reg_src;
+       char *string;
+       int rc;
+
+       if (desc == NULL || arguments == NULL || arguments[1] == NULL || arguments[2] == NULL || count < 4)
+               return -1;
+
+       value = desc->value;
+
+       string = arguments[1];
+       if (string[0] == 'r')
+               string = &string[1];
+
+       reg_dst = atoi(string);
+       value |= (reg_dst & PCM_OP_EQ_REG_DST_MASK) << PCM_OP_EQ_REG_DST_SHIFT;
+
+       string = arguments[2];
+       if (string[0] == 'r')
+               string = &string[1];
+
+       reg_src = atoi(string);
+       value |= (reg_src & PCM_OP_EQ_REG_SRC_MASK) << PCM_OP_EQ_REG_SRC_SHIFT;
+
+       rc = pcm_ops_asm_format(value, "%s r%d r%d", arguments[0], reg_dst, reg_src);
+       if (rc < 0)
+               return -1;
+
+       rc = pcm_op_immediate_asm(&arguments[3], 1);
+       if (rc < 0)
+               return -1;
+
+       return 3;
+}
+
+static int pcm_op_eq_disasm(struct pcm_op_desc *desc, unsigned int *arguments, unsigned int count)
+{
+       unsigned int value;
+       unsigned int reg_dst;
+       unsigned int reg_src;
+       char c;
+       int rc;
+
+       if (desc == NULL || arguments == NULL || count < 2)
+               return -1;
+
+       value = arguments[0];
+       reg_dst = (value >> PCM_OP_EQ_REG_DST_SHIFT) & PCM_OP_EQ_REG_DST_MASK;
+       reg_src = (value >> PCM_OP_EQ_REG_SRC_SHIFT) & PCM_OP_EQ_REG_SRC_MASK;
+
+       rc = pcm_ops_disasm_format(value, "%s r%d r%d", desc->mnemonic, reg_dst, reg_src);
+       if (rc < 0)
+               return -1;
+
+       rc = pcm_op_immediate_disasm(&arguments[1], 1);
+       if (rc < 0)
+               return -1;
+
+       return 1;
+}
+
 static int pcm_op_and_asm(struct pcm_op_desc *desc, char *arguments[], unsigned int count)
 {
        unsigned int value;
@@ -633,6 +697,14 @@ static struct pcm_op_desc pcm_op_descs[] = {
                .disasm_callback = pcm_op_dummy_disasm,
        },
        {
+               .mnemonic = "eq",
+               .mask = PCM_OP_EQ_MASK,
+               .value = PCM_OP_EQ_VALUE,
+               .padding = 0,
+               .asm_callback = pcm_op_eq_asm,
+               .disasm_callback = pcm_op_eq_disasm,
+       },
+       {
                .mnemonic = "and",
                .mask = PCM_OP_AND_MASK,
                .value = PCM_OP_AND_VALUE,
index 413f1d0..3e23141 100644 (file)
--- a/pcm/pcm.h
+++ b/pcm/pcm.h
 #define PCM_OP_NOP_MASK                                                0xffffffff
 #define PCM_OP_NOP_VALUE                                       0x17c07c1f
 
+#define PCM_OP_EQ_MASK                                         0xfc2ffff0
+#define PCM_OP_EQ_VALUE                                                0x68200000
+#define PCM_OP_EQ_REG_DST_SHIFT                                        22
+#define PCM_OP_EQ_REG_DST_MASK                                 0x0f
+#define PCM_OP_EQ_REG_SRC_SHIFT                                        0
+#define PCM_OP_EQ_REG_SRC_MASK                                 0x0f
+
 #define PCM_OP_AND_MASK                                                0xfc2ffff0
 #define PCM_OP_AND_VALUE                                       0x88000000
 #define PCM_OP_AND_REG_DST_SHIFT                               22