+#define MONO_EMIT_NEW_MOVE(cfg,dest,offset,src,imm,size) do { \
+ MonoInst *inst; \
+ int tmpr = 0; \
+ int sReg, dReg; \
+ MONO_INST_NEW (cfg, inst, OP_NOP); \
+ if (size > 256) { \
+ inst->dreg = dest; \
+ inst->inst_offset = offset; \
+ inst->sreg1 = src; \
+ inst->inst_imm = imm; \
+ } else { \
+ if (s390_is_uimm12(offset)) { \
+ inst->dreg = dest; \
+ inst->inst_offset = offset; \
+ } else { \
+ dReg = mono_alloc_preg (cfg); \
+ MONO_EMIT_NEW_BIALU_IMM(cfg, OP_ADD_IMM, \
+ dReg, dest, offset); \
+ inst->dreg = dReg; \
+ inst->inst_offset = 0; \
+ } \
+ if (s390_is_uimm12(imm)) { \
+ inst->sreg1 = src; \
+ inst->inst_imm = imm; \
+ } else { \
+ sReg = mono_alloc_preg (cfg); \
+ MONO_EMIT_NEW_BIALU_IMM(cfg, OP_ADD_IMM, \
+ sReg, src, imm); \
+ inst->sreg1 = sReg; \
+ inst->inst_imm = 0; \
+ } \
+ } \
+ inst->opcode = OP_S390_MOVE; \
+ inst->backend.size = size; \
+ MONO_ADD_INS (cfg->cbb, inst); \
+ } while (0)
+
+#define MONO_OUTPUT_VTR(cfg, size, dr, sr, so) do { \
+ int reg = mono_alloc_preg (cfg); \
+ switch (size) { \
+ case 0: \
+ MONO_EMIT_NEW_ICONST(cfg, reg, 0); \
+ mono_call_inst_add_outarg_reg(cfg, call, reg, dr, FALSE); \
+ break; \
+ case 1: \
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU1_MEMBASE, \
+ reg, sr, so); \
+ mono_call_inst_add_outarg_reg(cfg, call, reg, dr, FALSE); \
+ break; \
+ case 2: \
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU2_MEMBASE, \
+ reg, sr, so); \
+ mono_call_inst_add_outarg_reg(cfg, call, reg, dr, FALSE); \
+ break; \
+ case 4: \
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOAD_MEMBASE, \
+ reg, sr, so); \
+ mono_call_inst_add_outarg_reg(cfg, call, reg, dr, FALSE); \
+ break; \
+ case 8: \
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOAD_MEMBASE, \
+ reg, sr, so); \
+ mono_call_inst_add_outarg_reg(cfg, call, reg, dr, FALSE); \
+ reg = mono_alloc_preg (cfg); \
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOAD_MEMBASE, \
+ reg, sr, so + sizeof (guint32)); \
+ mono_call_inst_add_outarg_reg(cfg, call, reg, dr + 1, FALSE); \
+ break; \
+ } \
+} while (0)
+
+#define MONO_OUTPUT_VTS(cfg, size, dr, dx, sr, so) do { \
+ int tmpr; \
+ switch (size) { \
+ case 0: \
+ tmpr = mono_alloc_preg (cfg); \
+ MONO_EMIT_NEW_ICONST(cfg, tmpr, 0); \
+ MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG, \
+ dr, dx, tmpr); \
+ break; \
+ case 1: \
+ tmpr = mono_alloc_preg (cfg); \
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU1_MEMBASE, \
+ tmpr, sr, so); \
+ MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG, \
+ dr, dx, tmpr); \
+ break; \
+ case 2: \
+ tmpr = mono_alloc_preg (cfg); \
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU2_MEMBASE, \
+ tmpr, sr, so); \
+ MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG, \
+ dr, dx, tmpr); \
+ break; \
+ case 4: \
+ case 8: \
+ MONO_EMIT_NEW_MOVE (cfg, dr, dx, sr, so, size); \
+ break; \
+ } \
+} while (0)
+