static int MPIDU_Segment_contig_unpack_external32_to_buf(DLOOP_Offset *blocks_p,
                                                        DLOOP_Type el_type,
                                                        DLOOP_Offset rel_off,
                                                        void *bufp,
                                                        void *v_paramp)
{
    int src_el_size, dest_el_size;
    struct MPIDU_Segment_piece_params *paramp = v_paramp;
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_SEGMENT_CONTIG_UNPACK_EXTERNAL32_TO_BUF);

    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_SEGMENT_CONTIG_UNPACK_EXTERNAL32_TO_BUF);

    src_el_size = MPIDU_Datatype_get_basic_size(el_type);
    dest_el_size = MPIDI_Datatype_get_basic_size_external32(el_type);
    MPIR_Assert(dest_el_size);

    /*
     * h  = handle value
     * do = datatype buffer offset
     * dp = datatype buffer pointer
     * up = unpack buffer pointer (current location, incremented as we go)
     * sz = size of datatype (guess we could get this from handle value if
     *      we wanted...)
     */
#ifdef MPID_SP_VERBOSE
    dbg_printf("\t[contig unpack [external32]: do=%d, dp=%x, up=%x, "
               "src_el_sz=%d, dest_el_sz=%d, blksz=%d]\n",
	       rel_off,
	       (unsigned) bufp,
	       (unsigned) paramp->u.unpack.unpack_buffer,
	       src_el_size,
	       dest_el_size,
	       (int) *blocks_p);
#endif

    /* TODO: DEAL WITH CASE WHERE ALL DATA DOESN'T FIT! */
    if ((src_el_size == dest_el_size) && (src_el_size == 1))
    {
        MPIR_Memcpy(((char *)bufp) + rel_off,
	       paramp->u.unpack.unpack_buffer, *blocks_p);
    }
    else if (is_float_type(el_type))
    {
        external32_float_convert(((char *) bufp) + rel_off,
				 paramp->u.unpack.unpack_buffer,
                                 dest_el_size, src_el_size, *blocks_p);
    }
    else
    {
        external32_basic_convert(((char *) bufp) + rel_off,
				 paramp->u.unpack.unpack_buffer,
                                 dest_el_size, src_el_size, *blocks_p);
    }
    paramp->u.unpack.unpack_buffer += (dest_el_size * (*blocks_p));

    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_SEGMENT_CONTIG_UNPACK_EXTERNAL32_TO_BUF);
    return 0;
}
示例#2
0
bool Grammar::is_object_type(const std::string& str) {
    return is_boolean_type(str) || is_character_type(str) || is_integer_type(str) || is_float_type(str) ||
           is_string_type(str);
}
示例#3
0
static MonoInst*
emit_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args, const MagicTypeInfo *info)
{
	int i = 0;
	const char *name = cmethod->name;
	MonoInst *ins;
	int type_index, stack_type;

	if (info->op_index == 2 && cfg->r4fp && SIZEOF_VOID_P == 4) {
		type_index = 3;
		stack_type = STACK_R4;
	} else {
		type_index = info->op_index;
		stack_type = info->stack_type;
	}

	if (!strcmp ("op_Implicit", name) || !strcmp ("op_Explicit", name)) {
		int source_size = type_size (cfg, fsig->params [0]);
		int dest_size = type_size (cfg, fsig->ret);

		switch (info->big_stack_type) {
		case STACK_I8:
			if (!is_int_type (fsig->params [0]) || !is_int_type (fsig->ret))
				return NULL;
			break;
		case STACK_R8:
			if (!is_float_type (fsig->params [0]) || !is_float_type (fsig->ret))
				return NULL;
			break;
		default:
			g_assert_not_reached ();
		}

		//4 -> 4 or 8 -> 8
		if (source_size == dest_size)
			return args [0];

		//4 -> 8
		if (source_size < dest_size)
			return emit_widen (cfg, info, args [0]->dreg);

		//8 -> 4
		return emit_narrow (cfg, info, args [0]->dreg);
	}

	if (!strcmp (".ctor", name)) {
		gboolean is_ldaddr = args [0]->opcode == OP_LDADDR;
		int arg0 = args [1]->dreg;
		int arg_size = type_size (cfg, fsig->params [0]);

		if (arg_size > SIZEOF_VOID_P) //8 -> 4
			arg0 = emit_narrow (cfg, info, arg0)->dreg;
		else if (arg_size < SIZEOF_VOID_P) //4 -> 8
			arg0 = emit_widen (cfg, info, arg0)->dreg;

		if (is_ldaddr) { /*Eliminate LDADDR if it's initing a local var*/
			int dreg = ((MonoInst*)args [0]->inst_p0)->dreg;
			NULLIFY_INS (args [0]);
			EMIT_NEW_UNALU (cfg, ins, info->move, dreg, arg0);
			cfg->has_indirection = TRUE;
		} else {
			EMIT_NEW_STORE_MEMBASE (cfg, ins, info->store_op, args [0]->dreg, 0, arg0);
		}
		return ins;
	}

	if (!strcmp ("op_Increment", name) || !strcmp ("op_Decrement", name)) {
		gboolean inc = !strcmp ("op_Increment", name);
		/* FIXME float inc is too complex to bother with*/
		//this is broken with ints too
		// if (!info->inc_op)
			return NULL;

		/* We have IR for inc/dec */
		MONO_INST_NEW (cfg, ins, inc ? info->inc_op : info->dec_op);
		ins->dreg = alloc_dreg (cfg, info->stack_type);
		ins->sreg1 = args [0]->dreg;
		ins->inst_imm = 1;
		ins->type = info->stack_type;
		MONO_ADD_INS (cfg->cbb, ins);
		return ins;
	}

	for (i = 0; i < sizeof (int_binop) / sizeof  (IntIntrisic); ++i) {
		if (!strcmp (int_binop [i].op_name, name)) {
			if (!int_binop [i].op_table [info->op_index])
				return NULL;
			g_assert (int_binop [i].op_table [type_index]);

			MONO_INST_NEW (cfg, ins, int_binop [i].op_table [type_index]);
			ins->dreg = alloc_dreg (cfg, stack_type);
			ins->sreg1 = args [0]->dreg;
	        ins->sreg2 = args [1]->dreg;
			ins->type = stack_type;
			MONO_ADD_INS (cfg->cbb, ins);
			return mono_decompose_opcode (cfg, ins);
		}
	}

	for (i = 0; i < sizeof (int_unnop) / sizeof  (IntIntrisic); ++i) {
		if (!strcmp (int_unnop [i].op_name, name)) {
			g_assert (int_unnop [i].op_table [type_index]);

			MONO_INST_NEW (cfg, ins, int_unnop [i].op_table [type_index]);
			ins->dreg = alloc_dreg (cfg, stack_type);
			ins->sreg1 = args [0]->dreg;
			ins->type = stack_type;
			MONO_ADD_INS (cfg->cbb, ins);
			return ins;
		}
	}

	for (i = 0; i < sizeof (int_cmpop) / sizeof  (IntIntrisic); ++i) {
		if (!strcmp (int_cmpop [i].op_name, name)) {
			short op_cmp = int_cmpop [i].op_table [type_index];

			g_assert (op_cmp);

			if (info->compare_op) {
				MONO_INST_NEW (cfg, ins, info->compare_op);
		        ins->dreg = -1;
				ins->sreg1 = args [0]->dreg;
		        ins->sreg2 = args [1]->dreg;
				MONO_ADD_INS (cfg->cbb, ins);

				MONO_INST_NEW (cfg, ins, op_cmp);
		        ins->dreg = alloc_preg (cfg);
				ins->type = STACK_I4;
				MONO_ADD_INS (cfg->cbb, ins);
			} else {
				MONO_INST_NEW (cfg, ins, op_cmp);
				guint32 fcmp_dreg = ins->dreg = alloc_ireg (cfg);
				ins->sreg1 = args [0]->dreg;
		        ins->sreg2 = args [1]->dreg;
				MONO_ADD_INS (cfg->cbb, ins);
				if (op_cmp == OP_FCLT_UN || op_cmp == OP_FCGT_UN || op_cmp == OP_RCLT_UN || op_cmp == OP_RCGT_UN) {
					/* we have to negate the result of this comparison:
					 *  - op_GreaterThanOrEqual maps to NOT x OP_FCLT_UN / OP_RCLT_UN
					 *  - op_LessThanOrEqual    maps to NOT x OP_FCGT_UN / OP_RCGT_UN
					 *
					 *  this matches generated bytecode by C# when doing the
					 *  same operations on float/double. the `_UN` suffix says
					 *  that if an operand is NaN, the result is true. If
					 *  OP_FCGE/OP_FCLE is used, it is mapped to instructions
					 *  on some architectures that don't detect NaN. For
					 *  example, on arm64 the condition `eq` doesn't respect
					 *  NaN results of a `fcmp` instruction.
					 */
					MONO_INST_NEW (cfg, ins, OP_ICOMPARE_IMM);
					ins->dreg = -1;
					ins->sreg1 = fcmp_dreg;
					ins->inst_imm = 0;
					MONO_ADD_INS (cfg->cbb, ins);

					MONO_INST_NEW (cfg, ins, OP_CEQ);
					ins->dreg = alloc_preg (cfg);
					ins->type = STACK_I4;
					MONO_ADD_INS (cfg->cbb, ins);
				}
			}

			return ins;
		}
	}

	return NULL;
}
 bool Type::is_float() const
 {
     return is_float_type(_type_info);
 }
示例#5
0
static MonoInst*
emit_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args, const MagicTypeInfo *info)
{
	int i = 0;
	const char *name = cmethod->name;
	MonoInst *ins;
	int type_index, stack_type;

	if (info->op_index == 2 && cfg->r4fp && SIZEOF_VOID_P == 4) {
		type_index = 3;
		stack_type = STACK_R4;
	} else {
		type_index = info->op_index;
		stack_type = info->stack_type;
	}

	if (!strcmp ("op_Implicit", name) || !strcmp ("op_Explicit", name)) {
		int source_size = type_size (cfg, fsig->params [0]);
		int dest_size = type_size (cfg, fsig->ret);

		switch (info->big_stack_type) {
		case STACK_I8:
			if (!is_int_type (fsig->params [0]) || !is_int_type (fsig->ret))
				return NULL;
			break;
		case STACK_R8:
			if (!is_float_type (fsig->params [0]) || !is_float_type (fsig->ret))
				return NULL;
			break;
		default:
			g_assert_not_reached ();
		}

		//4 -> 4 or 8 -> 8
		if (source_size == dest_size)
			return args [0];

		//4 -> 8
		if (source_size < dest_size)
			return emit_widen (cfg, info, args [0]->dreg);

		//8 -> 4
		return emit_narrow (cfg, info, args [0]->dreg);
	}

	if (!strcmp (".ctor", name)) {
		gboolean is_ldaddr = args [0]->opcode == OP_LDADDR;
		int arg0 = args [1]->dreg;
		int arg_size = type_size (cfg, fsig->params [0]);

		if (arg_size > SIZEOF_VOID_P) //8 -> 4
			arg0 = emit_narrow (cfg, info, arg0)->dreg;
		else if (arg_size < SIZEOF_VOID_P) //4 -> 8
			arg0 = emit_widen (cfg, info, arg0)->dreg;

		if (is_ldaddr) { /*Eliminate LDADDR if it's initing a local var*/
			int dreg = ((MonoInst*)args [0]->inst_p0)->dreg;
			NULLIFY_INS (args [0]);
			EMIT_NEW_UNALU (cfg, ins, info->move, dreg, arg0);
			cfg->has_indirection = TRUE;
		} else {
			EMIT_NEW_STORE_MEMBASE (cfg, ins, info->store_op, args [0]->dreg, 0, arg0);
		}
		return ins;
	}

	if (!strcmp ("op_Increment", name) || !strcmp ("op_Decrement", name)) {
		gboolean inc = !strcmp ("op_Increment", name);
		/* FIXME float inc is too complex to bother with*/
		//this is broken with ints too
		// if (!info->inc_op)
			return NULL;

		/* We have IR for inc/dec */
		MONO_INST_NEW (cfg, ins, inc ? info->inc_op : info->dec_op);
		ins->dreg = alloc_dreg (cfg, info->stack_type);
		ins->sreg1 = args [0]->dreg;
		ins->inst_imm = 1;
		ins->type = info->stack_type;
		MONO_ADD_INS (cfg->cbb, ins);
		return ins;
	}

	for (i = 0; i < sizeof (int_binop) / sizeof  (IntIntrisic); ++i) {
		if (!strcmp (int_binop [i].op_name, name)) {
			if (!int_binop [i].op_table [info->op_index])
				return NULL;
			g_assert (int_binop [i].op_table [type_index]);

			MONO_INST_NEW (cfg, ins, int_binop [i].op_table [type_index]);
			ins->dreg = alloc_dreg (cfg, stack_type);
			ins->sreg1 = args [0]->dreg;
	        ins->sreg2 = args [1]->dreg;
			ins->type = stack_type;
			MONO_ADD_INS (cfg->cbb, ins);
			return mono_decompose_opcode (cfg, ins);
		}
	}

	for (i = 0; i < sizeof (int_unnop) / sizeof  (IntIntrisic); ++i) {
		if (!strcmp (int_unnop [i].op_name, name)) {
			g_assert (int_unnop [i].op_table [type_index]);

			MONO_INST_NEW (cfg, ins, int_unnop [i].op_table [type_index]);
			ins->dreg = alloc_dreg (cfg, stack_type);
			ins->sreg1 = args [0]->dreg;
			ins->type = stack_type;
			MONO_ADD_INS (cfg->cbb, ins);
			return ins;
		}
	}

	for (i = 0; i < sizeof (int_cmpop) / sizeof  (IntIntrisic); ++i) {
		if (!strcmp (int_cmpop [i].op_name, name)) {
			g_assert (int_cmpop [i].op_table [type_index]);

			if (info->compare_op) {
				MONO_INST_NEW (cfg, ins, info->compare_op);
		        ins->dreg = -1;
				ins->sreg1 = args [0]->dreg;
		        ins->sreg2 = args [1]->dreg;
				MONO_ADD_INS (cfg->cbb, ins);

				MONO_INST_NEW (cfg, ins, int_cmpop [i].op_table [type_index]);
		        ins->dreg = alloc_preg (cfg);
				ins->type = STACK_I4;
				MONO_ADD_INS (cfg->cbb, ins);
			} else {
				MONO_INST_NEW (cfg, ins, int_cmpop [i].op_table [type_index]);
				ins->dreg = alloc_ireg (cfg);
				ins->sreg1 = args [0]->dreg;
		        ins->sreg2 = args [1]->dreg;
				MONO_ADD_INS (cfg->cbb, ins);
			}

			return ins;
		}
	}

	return NULL;
}
示例#6
0
文件: stat.c 项目: daveshields/AdaEd
void gen_condition(Node node, Symbol destination, int branch_cond)
															/*;gen_condition*/
{
	/* IMPORTANT WARNING: destination is where to go when expression is
	 *                    equal to branch_cond
	 */
	/* These maps are realized in procedures immediately following.
	 *  const
	 * jump_false_code = {
	 *    ['=', I_JUMP_IF_FALSE],
	 *    ['!=', I_JUMP_IF_TRUE],
	 *    ['<', I_JUMP_IF_GREATER_OR_EQUAL],
	 *    ['>', I_JUMP_IF_LESS_OR_EQUAL],
	 *    ['<=', I_JUMP_IF_GREATER],
	 *    ['>=', I_JUMP_IF_LESS] },
	 * 
	 * jump_true_code = {
	 *    ['=', I_JUMP_IF_TRUE],
	 *    ['<', I_JUMP_IF_LESS],
	 *    ['>', I_JUMP_IF_GREATER],
	 *    ['<=', I_JUMP_IF_LESS_OR_EQUAL],
	 *    ['>=', I_JUMP_IF_GREATER_OR_EQUAL] };
	 */

	Tuple	tup;
	Node	opnode, args, op1, op2;
	Symbol	opcode, optype;

#ifdef TRACE
	if (debug_flag)
		gen_trace_node("GEN_CONDITION", node);
#endif

	if (N_KIND(node) == as_op) {
		opnode = N_AST1(node);
		args = N_AST2(node);
		opcode  = N_UNQ(opnode);
		if (opcode == symbol_eq || opcode == symbol_ne || opcode == symbol_lt
		  || opcode == symbol_gt || opcode == symbol_le || opcode == symbol_ge){
			tup = N_LIST(args);
			op1 = (Node) tup[1];
			op2     = (Node) tup[2];

			gen_value(op1);
			gen_value(op2);
			optype = get_type(op1);
			if (is_simple_type(optype)) {
				if (is_float_type(optype))
					gen_k(I_FLOAT_COMPARE, kind_of(optype));
				else
					gen_k(I_COMPARE, kind_of(optype));
			}
			else {
				if (is_record_type(optype)) {
					gen_s(I_PUSH_EFFECTIVE_ADDRESS, optype);
				}
				if (is_array_type(optype) && 
				    (opcode != symbol_eq) && (opcode != symbol_ne)) {
					gen(I_COMPARE_ARRAYS);
				}
				else {
					gen(I_COMPARE_STRUC);
				}
			}
		}
		else {
			gen_value(node);
			opcode = symbol_eq;
		}
	}
	else {
		gen_value(node);
		opcode = symbol_eq;
	}

	if (branch_cond)
		gen_s(jump_true_code(opcode), destination);
	else
		gen_s(jump_false_code(opcode), destination);
}