From 5b224ec94da5cef4562ed834a5f0a5a4b7655da3 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Sun, 14 Feb 2016 17:07:44 +0100 Subject: [PATCH] Fix the asmjs ABI --- src/librustc_trans/trans/cabi_asmjs.rs | 58 ++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/src/librustc_trans/trans/cabi_asmjs.rs b/src/librustc_trans/trans/cabi_asmjs.rs index 823f333f3317b..3a4a6b9960e9c 100644 --- a/src/librustc_trans/trans/cabi_asmjs.rs +++ b/src/librustc_trans/trans/cabi_asmjs.rs @@ -8,15 +8,65 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use trans::cabi::FnType; -use trans::cabi_arm; +#![allow(non_upper_case_globals)] + +use llvm::{Struct, Array, Attribute}; +use trans::cabi::{FnType, ArgType}; use trans::context::CrateContext; use trans::type_::Type; +// Data layout: e-p:32:32-i64:64-v128:32:128-n32-S128 + +// See the https://github.com/kripken/emscripten-fastcomp-clang repository. +// The class `EmscriptenABIInfo` in `/lib/CodeGen/TargetInfo.cpp` contains the ABI definitions. + +fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType { + match ty.kind() { + Struct => { + let field_types = ty.field_types(); + if field_types.len() == 1 { + ArgType::direct(ty, Some(field_types[0]), None, None) + } else { + ArgType::indirect(ty, Some(Attribute::StructRet)) + } + }, + Array => { + ArgType::indirect(ty, Some(Attribute::StructRet)) + }, + _ => { + let attr = if ty == Type::i1(ccx) { Some(Attribute::ZExt) } else { None }; + ArgType::direct(ty, None, None, attr) + } + } +} + +fn classify_arg_ty(ccx: &CrateContext, ty: Type) -> ArgType { + if ty.is_aggregate() { + ArgType::indirect(ty, Some(Attribute::ByVal)) + } else { + let attr = if ty == Type::i1(ccx) { Some(Attribute::ZExt) } else { None }; + ArgType::direct(ty, None, None, attr) + } +} + pub fn compute_abi_info(ccx: &CrateContext, atys: &[Type], rty: Type, ret_def: bool) -> FnType { - cabi_arm::compute_abi_info(ccx, atys, rty, ret_def, - cabi_arm::Flavor::General) + let mut arg_tys = Vec::new(); + for &aty in atys { + let ty = classify_arg_ty(ccx, aty); + arg_tys.push(ty); + } + + let ret_ty = if ret_def { + classify_ret_ty(ccx, rty) + } else { + ArgType::direct(Type::void(ccx), None, None, None) + }; + + return FnType { + arg_tys: arg_tys, + ret_ty: ret_ty, + }; }