pcm: Add support for and operation
authorPaul Kocialkowski <contact@paulk.fr>
Tue, 28 Feb 2017 14:40:15 +0000 (15:40 +0100)
committerPaul Kocialkowski <contact@paulk.fr>
Tue, 28 Feb 2017 16:36:47 +0000 (17:36 +0100)
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
pcm/pcm.c
pcm/pcm.h

index 2cddaf4..4126156 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_and_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_AND_REG_DST_MASK) << PCM_OP_AND_REG_DST_SHIFT;
+
+       string = arguments[2];
+       if (string[0] == 'r')
+               string = &string[1];
+
+       reg_src = atoi(string);
+       value |= (reg_src & PCM_OP_AND_REG_SRC_MASK) << PCM_OP_AND_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_and_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_AND_REG_DST_SHIFT) & PCM_OP_AND_REG_DST_MASK;
+       reg_src = (value >> PCM_OP_AND_REG_SRC_SHIFT) & PCM_OP_AND_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_load_asm(struct pcm_op_desc *desc, char *arguments[], unsigned int count)
 {
        unsigned int value;
@@ -447,6 +511,14 @@ static struct pcm_op_desc pcm_op_descs[] = {
                .disasm_callback = pcm_op_dummy_disasm,
        },
        {
+               .mnemonic = "and",
+               .mask = PCM_OP_AND_MASK,
+               .value = PCM_OP_AND_VALUE,
+               .padding = 0,
+               .asm_callback = pcm_op_and_asm,
+               .disasm_callback = pcm_op_and_disasm,
+       },
+       {
                .mnemonic = "load",
                .mask = PCM_OP_LOAD_MASK,
                .value = PCM_OP_LOAD_VALUE,
index fa88742..d77e924 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_AND_MASK                                                0xfc000000
+#define PCM_OP_AND_VALUE                                       0x88000000
+#define PCM_OP_AND_REG_DST_SHIFT                               22
+#define PCM_OP_AND_REG_DST_MASK                                        0x0f
+#define PCM_OP_AND_REG_SRC_SHIFT                               0
+#define PCM_OP_AND_REG_SRC_MASK                                        0x0f
+
 #define PCM_OP_LOAD_MASK                                       0xfc0000ff
 #define PCM_OP_LOAD_VALUE                                      0x1800001f
 #define PCM_OP_LOAD_REG_SHIFT                                  22