+/**
+ * Get the register class which shall be used to store a value of a given mode.
+ * @param self The this pointer.
+ * @param mode The mode in question.
+ * @return A register class which can hold values of the given mode.
+ */
+const arch_register_class_t *ia32_get_reg_class_for_mode(const void *self, const ir_mode *mode) {
+ if (mode_is_float(mode))
+ return &ia32_reg_classes[CLASS_ia32_fp];
+ else
+ return &ia32_reg_classes[CLASS_ia32_gp];
+}
+
+/**
+ * Get the ABI restrictions for procedure calls.
+ * @param self The this pointer.
+ * @param method_type The type of the method (procedure) in question.
+ * @param abi The abi object to be modified
+ */
+void ia32_get_call_abi(const void *self, ir_type *method_type, be_abi_call_t *abi) {
+ ir_type *tp;
+ ir_mode *mode;
+ unsigned cc = get_method_calling_convention(method_type);
+ int n = get_method_n_params(method_type);
+ int biggest_n = -1;
+ int stack_idx = 0;
+ int i, ignore;
+ ir_mode **modes;
+ const arch_register_t *reg;
+
+ /* set stack parameter passing style */
+ be_abi_call_set_flags(abi, BE_ABI_LEFT_TO_RIGHT);
+
+ /* collect the mode for each type */
+ modes = alloca(n * sizeof(modes[0]));
+
+ for (i = 0; i < n; i++) {
+ tp = get_method_param_type(method_type, i);
+ modes[i] = get_type_mode(tp);
+ }
+
+ /* set register parameters */
+ if (cc & cc_reg_param) {
+ /* determine the number of parameters passed via registers */
+ biggest_n = ia32_get_n_regparam_class(n, modes, &ignore, &ignore);
+
+ /* loop over all parameters and set the register requirements */
+ for (i = 0; i <= biggest_n; i++) {
+ reg = ia32_get_RegParam_reg(n, modes, i, cc);
+ assert(reg && "kaputt");
+ be_abi_call_param_reg(abi, i, reg);
+ }
+
+ stack_idx = i;
+ }
+
+
+ /* set stack parameters */
+ for (i = stack_idx; i < n; i++) {
+ be_abi_call_param_stack(abi, i);
+ }
+
+
+ /* set return registers */
+ n = get_method_n_ress(method_type);
+
+ assert(n <= 2 && "more than two results not supported");
+
+ /* In case of 64bit returns, we will have two 32bit values */
+ if (n == 2) {
+ tp = get_method_res_type(method_type, 0);
+ mode = get_type_mode(tp);
+
+ assert(!mode_is_float(mode) && "two FP results not supported");
+
+ tp = get_method_res_type(method_type, 1);
+ mode = get_type_mode(tp);
+
+ assert(!mode_is_float(mode) && "two FP results not supported");
+
+ be_abi_call_res_reg(abi, 0, &ia32_gp_regs[REG_EAX]);
+ be_abi_call_res_reg(abi, 1, &ia32_gp_regs[REG_EDX]);
+ }
+ else if (n == 1) {
+ tp = get_method_res_type(method_type, 0);
+ mode = get_type_mode(tp);
+
+ if (mode_is_float(mode)) {
+ be_abi_call_res_reg(abi, 1, &ia32_fp_regs[REG_XMM0]);
+ }
+ else {
+ be_abi_call_res_reg(abi, 1, &ia32_gp_regs[REG_EAX]);
+ }
+ }
+}
+
+