guess_execution_size(insn, dest);
}
+extern int reg_type_size[];
+
static void
validate_reg(struct brw_instruction *insn, struct brw_reg reg)
{
int execsize_for_reg[] = {1, 2, 4, 8, 16};
int width, hstride, vstride, execsize;
- if (reg.file == BRW_IMMEDIATE_VALUE)
+ if (reg.file == BRW_IMMEDIATE_VALUE) {
+ /* 3.3.6: Region Parameters. Restriction: Immediate vectors
+ * mean the destination has to be 128-bit aligned and the
+ * destination horiz stride has to be a word.
+ */
+ if (reg.type == BRW_REGISTER_TYPE_V) {
+ assert(hstride_for_reg[insn->bits1.da1.dest_horiz_stride] *
+ reg_type_size[insn->bits1.da1.dest_reg_type] == 2);
+ }
+
return;
+ }
if (reg.file == BRW_ARCHITECTURE_REGISTER_FILE &&
reg.file == BRW_ARF_NULL)
ALU2(RSR)
ALU2(RSL)
ALU2(ASR)
-ALU2(ADD)
-ALU2(MUL)
ALU1(FRC)
ALU1(RNDD)
ALU1(RNDZ)
ALU2(LINE)
ALU2(PLN)
+struct brw_instruction *brw_ADD(struct brw_compile *p,
+ struct brw_reg dest,
+ struct brw_reg src0,
+ struct brw_reg src1)
+{
+ /* 6.2.2: add */
+ if (src0.type == BRW_REGISTER_TYPE_F ||
+ (src0.file == BRW_IMMEDIATE_VALUE &&
+ src0.type == BRW_REGISTER_TYPE_VF)) {
+ assert(src1.type != BRW_REGISTER_TYPE_UD);
+ assert(src1.type != BRW_REGISTER_TYPE_D);
+ }
+
+ if (src1.type == BRW_REGISTER_TYPE_F ||
+ (src1.file == BRW_IMMEDIATE_VALUE &&
+ src1.type == BRW_REGISTER_TYPE_VF)) {
+ assert(src0.type != BRW_REGISTER_TYPE_UD);
+ assert(src0.type != BRW_REGISTER_TYPE_D);
+ }
+
+ return brw_alu2(p, BRW_OPCODE_ADD, dest, src0, src1);
+}
+
+struct brw_instruction *brw_MUL(struct brw_compile *p,
+ struct brw_reg dest,
+ struct brw_reg src0,
+ struct brw_reg src1)
+{
+ /* 6.32.38: mul */
+ if (src0.type == BRW_REGISTER_TYPE_D ||
+ src0.type == BRW_REGISTER_TYPE_UD ||
+ src1.type == BRW_REGISTER_TYPE_D ||
+ src1.type == BRW_REGISTER_TYPE_UD) {
+ assert(dest.type != BRW_REGISTER_TYPE_F);
+ }
+
+ if (src0.type == BRW_REGISTER_TYPE_F ||
+ (src0.file == BRW_IMMEDIATE_VALUE &&
+ src0.type == BRW_REGISTER_TYPE_VF)) {
+ assert(src1.type != BRW_REGISTER_TYPE_UD);
+ assert(src1.type != BRW_REGISTER_TYPE_D);
+ }
+
+ if (src1.type == BRW_REGISTER_TYPE_F ||
+ (src1.file == BRW_IMMEDIATE_VALUE &&
+ src1.type == BRW_REGISTER_TYPE_VF)) {
+ assert(src0.type != BRW_REGISTER_TYPE_UD);
+ assert(src0.type != BRW_REGISTER_TYPE_D);
+ }
+
+ assert(src0.file != BRW_ARCHITECTURE_REGISTER_FILE ||
+ src0.nr != BRW_ARF_ACCUMULATOR);
+ assert(src1.file != BRW_ARCHITECTURE_REGISTER_FILE ||
+ src1.nr != BRW_ARF_ACCUMULATOR);
+
+ return brw_alu2(p, BRW_OPCODE_MUL, dest, src0, src1);
+}
void brw_NOP(struct brw_compile *p)
struct brw_instruction *insn;
GLuint br = 1;
- if (intel->gen == 5)
+ /* jump count is for 64bit data chunk each, so one 128bit
+ instruction requires 2 chunks. */
+ if (intel->gen >= 5)
br = 2;
if (p->single_program_flow) {
struct intel_context *intel = &p->brw->intel;
GLuint br = 1;
- if (intel->gen == 5)
+ if (intel->gen >= 5)
br = 2;
if (p->single_program_flow) {
struct brw_instruction *insn;
GLuint br = 1;
- if (intel->gen == 5)
+ if (intel->gen >= 5)
br = 2;
if (p->single_program_flow)
struct brw_instruction *landing = &p->store[p->nr_insn];
GLuint jmpi = 1;
- if (intel->gen == 5)
+ if (intel->gen >= 5)
jmpi = 2;
assert(jmp_insn->header.opcode == BRW_OPCODE_JMPI);
}
}
+/** Extended math function, float[8].
+ */
+void brw_math2(struct brw_compile *p,
+ struct brw_reg dest,
+ GLuint function,
+ struct brw_reg src0,
+ struct brw_reg src1)
+{
+ struct intel_context *intel = &p->brw->intel;
+ struct brw_instruction *insn = next_insn(p, BRW_OPCODE_MATH);
+
+ assert(intel->gen >= 6);
+
+ /* Math is the same ISA format as other opcodes, except that CondModifier
+ * becomes FC[3:0] and ThreadCtrl becomes FC[5:4].
+ */
+ insn->header.destreg__conditionalmod = function;
+
+ brw_set_dest(insn, dest);
+ brw_set_src0(insn, src0);
+ brw_set_src1(insn, src1);
+}
+
/**
* Extended math function, float[16].
* Use 2 send instructions.
GLuint response_length,
GLboolean eot)
{
- struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+ struct intel_context *intel = &p->brw->intel;
+ struct brw_instruction *insn;
+ /* Sandybridge doesn't have the implied move for SENDs,
+ * and the first message register index comes from src0.
+ */
+ if (intel->gen >= 6) {
+ brw_push_insn_state(p);
+ brw_set_mask_control( p, BRW_MASK_DISABLE );
+ brw_MOV(p, brw_message_reg(msg_reg_nr), src0);
+ brw_pop_insn_state(p);
+ src0 = brw_message_reg(msg_reg_nr);
+ }
+
+ insn = next_insn(p, BRW_OPCODE_SEND);
brw_set_dest(insn, dest);
brw_set_src0(insn, src0);
brw_set_src1(insn, brw_imm_d(0));
- insn->header.destreg__conditionalmod = msg_reg_nr;
+ if (intel->gen < 6)
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_ff_sync_message(p->brw,
insn,