#include "midgard.h"
#include "midgard-parse.h"
#include "disassemble.h"
+#include "helpers.h"
#include "util/half_float.h"
#define DEFINE_CASE(define, str) case define: { printf(str); break; }
static void
print_vector_src(unsigned src_binary, bool out_high,
- bool out_half, unsigned reg)
+ bool out_half, unsigned reg,
+ bool is_int)
{
midgard_vector_alu_src *src = (midgard_vector_alu_src *)&src_binary;
- if (src->negate)
- printf("-");
+ /* Modifiers change meaning depending on the op's context */
+
+ midgard_int_mod int_mod = src->mod;
+
+ if (is_int) {
+ switch (int_mod) {
+ case midgard_int_sign_extend:
+ printf("sext(");
+ break;
+ case midgard_int_zero_extend:
+ printf("zext(");
+ break;
+ case midgard_int_reserved:
+ printf("unk(");
+ break;
+ case midgard_int_normal:
+ /* Implicit */
+ break;
+ }
+ } else {
+ if (src->mod & MIDGARD_FLOAT_MOD_NEG)
+ printf("-");
- if (src->abs)
- printf("abs(");
+ if (src->mod & MIDGARD_FLOAT_MOD_ABS)
+ printf("abs(");
+ }
//register
printf("%c", c[(src->swizzle >> (i * 2)) & 3]);
}
- if (src->abs)
+ /* Since we wrapped with a function-looking thing */
+
+ if ((is_int && (int_mod != midgard_int_normal))
+ || (!is_int && src->mod & MIDGARD_FLOAT_MOD_ABS))
printf(")");
}
printf(", ");
- print_vector_src(alu_field->src1, out_high, half, reg_info->src1_reg);
+ bool is_int = midgard_is_integer_op(alu_field->op);
+ print_vector_src(alu_field->src1, out_high, half, reg_info->src1_reg, is_int);
printf(", ");
print_immediate(imm);
} else {
print_vector_src(alu_field->src2, out_high, half,
- reg_info->src2_reg);
+ reg_info->src2_reg, is_int);
}
printf("\n");
midgard_dest_override_none = 2
} midgard_dest_override;
+typedef enum {
+ midgard_int_sign_extend = 0,
+ midgard_int_zero_extend = 1,
+ midgard_int_normal = 2,
+ midgard_int_reserved = 3
+} midgard_int_mod;
+
+#define MIDGARD_FLOAT_MOD_ABS (1 << 0)
+#define MIDGARD_FLOAT_MOD_NEG (1 << 1)
+
typedef struct
__attribute__((__packed__))
{
- bool abs : 1;
- bool negate : 1;
+ /* Either midgard_int_mod or from midgard_float_mod_*, depending on the
+ * type of op */
+ unsigned mod : 2;
/* replicate lower half if dest = half, or low/high half selection if
* dest = full
if (!src) return blank_alu_src;
midgard_vector_alu_src alu_src = {
- .abs = src->abs,
- .negate = src->negate,
+ .mod = (src->abs << 0) | (src->negate << 1),
.rep_low = 0,
.rep_high = 0,
.half = 0, /* TODO */
emit_mir_instruction(ctx, ins);
}
- /* vadd.u2f hr2, abs(hr2), #0 */
+ /* vadd.u2f hr2, zext(hr2), #0 */
midgard_vector_alu_src alu_src = blank_alu_src;
- alu_src.abs = true;
+ alu_src.mod = midgard_int_zero_extend;
alu_src.half = true;
midgard_instruction u2f = {
/* vmul.fmul.sat r1, hr2, #0.00392151 */
- alu_src.abs = false;
+ alu_src.mod = 0;
midgard_instruction fmul = {
.type = TAG_ALU_4,
midgard_vector_alu_src v;
memcpy(&v, &u, sizeof(v));
+ /* TODO: Integers */
+
midgard_scalar_alu_src s = {
- .abs = v.abs,
- .negate = v.negate,
+ .abs = v.mod & MIDGARD_FLOAT_MOD_ABS,
+ .negate = v.mod & MIDGARD_FLOAT_MOD_NEG,
.full = !v.half,
.component = (v.swizzle & 3) << 1
};
/* We don't know how to handle these with a constant */
- if (src->abs || src->negate || src->half || src->rep_low || src->rep_high) {
+ if (src->mod || src->half || src->rep_low || src->rep_high) {
DBG("Bailing inline constant...\n");
continue;
}