Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: src/arm/macro-assembler-arm.cc

Issue 6874007: Implement hardfloat calling convention in macro assembler and simulator. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add num_double_arguments to CallCFunction Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/arm/simulator-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } 279 }
280 280
281 281
282 void MacroAssembler::Move(Register dst, Register src) { 282 void MacroAssembler::Move(Register dst, Register src) {
283 if (!dst.is(src)) { 283 if (!dst.is(src)) {
284 mov(dst, src); 284 mov(dst, src);
285 } 285 }
286 } 286 }
287 287
288 288
289 void MacroAssembler::Move(DoubleRegister dst, DoubleRegister src) {
290 ASSERT(CpuFeatures::IsSupported(VFP3));
291 CpuFeatures::Scope scope(VFP3);
292 if (!dst.is(src)) {
293 vmov(dst, src);
294 }
295 }
296
297
289 void MacroAssembler::And(Register dst, Register src1, const Operand& src2, 298 void MacroAssembler::And(Register dst, Register src1, const Operand& src2,
290 Condition cond) { 299 Condition cond) {
291 if (!src2.is_reg() && 300 if (!src2.is_reg() &&
292 !src2.must_use_constant_pool() && 301 !src2.must_use_constant_pool() &&
293 src2.immediate() == 0) { 302 src2.immediate() == 0) {
294 mov(dst, Operand(0, RelocInfo::NONE), LeaveCC, cond); 303 mov(dst, Operand(0, RelocInfo::NONE), LeaveCC, cond);
295 304
296 } else if (!src2.is_single_instruction() && 305 } else if (!src2.is_single_instruction() &&
297 !src2.must_use_constant_pool() && 306 !src2.must_use_constant_pool() &&
298 CpuFeatures::IsSupported(ARMv7) && 307 CpuFeatures::IsSupported(ARMv7) &&
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 841
833 // Tear down the exit frame, pop the arguments, and return. 842 // Tear down the exit frame, pop the arguments, and return.
834 mov(sp, Operand(fp)); 843 mov(sp, Operand(fp));
835 ldm(ia_w, sp, fp.bit() | lr.bit()); 844 ldm(ia_w, sp, fp.bit() | lr.bit());
836 if (argument_count.is_valid()) { 845 if (argument_count.is_valid()) {
837 add(sp, sp, Operand(argument_count, LSL, kPointerSizeLog2)); 846 add(sp, sp, Operand(argument_count, LSL, kPointerSizeLog2));
838 } 847 }
839 } 848 }
840 849
841 void MacroAssembler::GetCFunctionDoubleResult(const DoubleRegister dst) { 850 void MacroAssembler::GetCFunctionDoubleResult(const DoubleRegister dst) {
842 vmov(dst, r0, r1); 851 if (FLAG_hardfloat) {
852 Move(dst, d0);
853 } else {
854 vmov(dst, r0, r1);
855 }
843 } 856 }
844 857
845 858
846 void MacroAssembler::InvokePrologue(const ParameterCount& expected, 859 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
847 const ParameterCount& actual, 860 const ParameterCount& actual,
848 Handle<Code> code_constant, 861 Handle<Code> code_constant,
849 Register code_reg, 862 Register code_reg,
850 Label* done, 863 Label* done,
851 InvokeFlag flag, 864 InvokeFlag flag,
852 CallWrapper* call_wrapper) { 865 CallWrapper* call_wrapper) {
(...skipping 1934 matching lines...) Expand 10 before | Expand all | Expand 10 after
2787 int kFlatAsciiStringMask = 2800 int kFlatAsciiStringMask =
2788 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; 2801 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask;
2789 int kFlatAsciiStringTag = ASCII_STRING_TYPE; 2802 int kFlatAsciiStringTag = ASCII_STRING_TYPE;
2790 and_(scratch, type, Operand(kFlatAsciiStringMask)); 2803 and_(scratch, type, Operand(kFlatAsciiStringMask));
2791 cmp(scratch, Operand(kFlatAsciiStringTag)); 2804 cmp(scratch, Operand(kFlatAsciiStringTag));
2792 b(ne, failure); 2805 b(ne, failure);
2793 } 2806 }
2794 2807
2795 static const int kRegisterPassedArguments = 4; 2808 static const int kRegisterPassedArguments = 4;
2796 2809
2797 void MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) { 2810
2811 int MacroAssembler::CalculateStackPassedWords(int num_reg_arguments,
2812 int num_double_arguments) {
2813 int stack_passed_words = 0;
2814 if (FLAG_hardfloat) {
2815 // In the hard floating point calling convention, we can use
2816 // all double registers to pass doubles.
2817 if (num_double_arguments > DoubleRegister::kNumRegisters) {
2818 stack_passed_words +=
2819 2 * (num_double_arguments - DoubleRegister::kNumRegisters);
2820 }
2821 } else {
2822 // In the soft floating point calling convention, every double
2823 // argument is passed using two registers.
2824 num_reg_arguments += 2 * num_double_arguments;
2825 }
2826 // Up to four simple arguments are passed in registers r0..r3.
2827 if (num_reg_arguments > kRegisterPassedArguments) {
2828 stack_passed_words += num_reg_arguments - kRegisterPassedArguments;
2829 }
2830 return stack_passed_words;
2831 }
2832
2833
2834 void MacroAssembler::PrepareCallCFunction(int num_reg_arguments,
2835 int num_double_arguments,
2836 Register scratch) {
2798 int frame_alignment = ActivationFrameAlignment(); 2837 int frame_alignment = ActivationFrameAlignment();
2799 2838 int stack_passed_arguments = CalculateStackPassedWords(
2800 // Up to four simple arguments are passed in registers r0..r3. 2839 num_reg_arguments, num_double_arguments);
2801 int stack_passed_arguments = (num_arguments <= kRegisterPassedArguments) ?
2802 0 : num_arguments - kRegisterPassedArguments;
2803 if (frame_alignment > kPointerSize) { 2840 if (frame_alignment > kPointerSize) {
2804 // Make stack end at alignment and make room for num_arguments - 4 words 2841 // Make stack end at alignment and make room for num_arguments - 4 words
2805 // and the original value of sp. 2842 // and the original value of sp.
2806 mov(scratch, sp); 2843 mov(scratch, sp);
2807 sub(sp, sp, Operand((stack_passed_arguments + 1) * kPointerSize)); 2844 sub(sp, sp, Operand((stack_passed_arguments + 1) * kPointerSize));
2808 ASSERT(IsPowerOf2(frame_alignment)); 2845 ASSERT(IsPowerOf2(frame_alignment));
2809 and_(sp, sp, Operand(-frame_alignment)); 2846 and_(sp, sp, Operand(-frame_alignment));
2810 str(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize)); 2847 str(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize));
2811 } else { 2848 } else {
2812 sub(sp, sp, Operand(stack_passed_arguments * kPointerSize)); 2849 sub(sp, sp, Operand(stack_passed_arguments * kPointerSize));
2813 } 2850 }
2814 } 2851 }
2815 2852
2816 2853
2854 void MacroAssembler::PrepareCallCFunction(int num_reg_arguments,
2855 Register scratch) {
2856 PrepareCallCFunction(num_reg_arguments, 0, scratch);
2857 }
2858
2859
2860 void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg) {
2861 if (FLAG_hardfloat) {
2862 Move(d0, dreg);
2863 } else {
2864 vmov(r0, r1, dreg);
2865 }
2866 }
2867
2868
2869 void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg1,
2870 DoubleRegister dreg2) {
2871 if (FLAG_hardfloat) {
2872 if (dreg2.is(d0)) {
2873 ASSERT(!dreg1.is(d1));
2874 Move(d1, dreg2);
2875 Move(d0, dreg1);
2876 } else {
2877 Move(d0, dreg1);
2878 Move(d1, dreg2);
2879 }
2880 } else {
2881 vmov(r0, r1, dreg1);
2882 vmov(r2, r3, dreg2);
2883 }
2884 }
2885
2886
2887 void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg,
2888 Register reg) {
2889 if (FLAG_hardfloat) {
2890 Move(d0, dreg);
2891 Move(r0, reg);
2892 } else {
2893 Move(r2, reg);
2894 vmov(r0, r1, dreg);
2895 }
2896 }
2897
2898
2899 void MacroAssembler::CallCFunction(ExternalReference function,
2900 int num_reg_arguments,
2901 int num_double_arguments) {
2902 CallCFunctionHelper(no_reg,
2903 function,
2904 ip,
2905 num_reg_arguments,
2906 num_double_arguments);
2907 }
2908
2909
2910 void MacroAssembler::CallCFunction(Register function,
2911 Register scratch,
2912 int num_reg_arguments,
2913 int num_double_arguments) {
2914 CallCFunctionHelper(function,
2915 ExternalReference::the_hole_value_location(isolate()),
2916 scratch,
2917 num_reg_arguments,
2918 num_double_arguments);
2919 }
2920
2921
2817 void MacroAssembler::CallCFunction(ExternalReference function, 2922 void MacroAssembler::CallCFunction(ExternalReference function,
2818 int num_arguments) { 2923 int num_arguments) {
2819 CallCFunctionHelper(no_reg, function, ip, num_arguments); 2924 CallCFunction(function, num_arguments, 0);
2820 } 2925 }
2821 2926
2927
2822 void MacroAssembler::CallCFunction(Register function, 2928 void MacroAssembler::CallCFunction(Register function,
2823 Register scratch, 2929 Register scratch,
2824 int num_arguments) { 2930 int num_arguments) {
2825 CallCFunctionHelper(function, 2931 CallCFunction(function, scratch, num_arguments, 0);
2826 ExternalReference::the_hole_value_location(isolate()),
2827 scratch,
2828 num_arguments);
2829 } 2932 }
2830 2933
2831 2934
2832 void MacroAssembler::CallCFunctionHelper(Register function, 2935 void MacroAssembler::CallCFunctionHelper(Register function,
2833 ExternalReference function_reference, 2936 ExternalReference function_reference,
2834 Register scratch, 2937 Register scratch,
2835 int num_arguments) { 2938 int num_reg_arguments,
2939 int num_double_arguments) {
2836 // Make sure that the stack is aligned before calling a C function unless 2940 // Make sure that the stack is aligned before calling a C function unless
2837 // running in the simulator. The simulator has its own alignment check which 2941 // running in the simulator. The simulator has its own alignment check which
2838 // provides more information. 2942 // provides more information.
2839 #if defined(V8_HOST_ARCH_ARM) 2943 #if defined(V8_HOST_ARCH_ARM)
2840 if (emit_debug_code()) { 2944 if (emit_debug_code()) {
2841 int frame_alignment = OS::ActivationFrameAlignment(); 2945 int frame_alignment = OS::ActivationFrameAlignment();
2842 int frame_alignment_mask = frame_alignment - 1; 2946 int frame_alignment_mask = frame_alignment - 1;
2843 if (frame_alignment > kPointerSize) { 2947 if (frame_alignment > kPointerSize) {
2844 ASSERT(IsPowerOf2(frame_alignment)); 2948 ASSERT(IsPowerOf2(frame_alignment));
2845 Label alignment_as_expected; 2949 Label alignment_as_expected;
2846 tst(sp, Operand(frame_alignment_mask)); 2950 tst(sp, Operand(frame_alignment_mask));
2847 b(eq, &alignment_as_expected); 2951 b(eq, &alignment_as_expected);
2848 // Don't use Check here, as it will call Runtime_Abort possibly 2952 // Don't use Check here, as it will call Runtime_Abort possibly
2849 // re-entering here. 2953 // re-entering here.
2850 stop("Unexpected alignment"); 2954 stop("Unexpected alignment");
2851 bind(&alignment_as_expected); 2955 bind(&alignment_as_expected);
2852 } 2956 }
2853 } 2957 }
2854 #endif 2958 #endif
2855 2959
2856 // Just call directly. The function called cannot cause a GC, or 2960 // Just call directly. The function called cannot cause a GC, or
2857 // allow preemption, so the return address in the link register 2961 // allow preemption, so the return address in the link register
2858 // stays correct. 2962 // stays correct.
2859 if (function.is(no_reg)) { 2963 if (function.is(no_reg)) {
2860 mov(scratch, Operand(function_reference)); 2964 mov(scratch, Operand(function_reference));
2861 function = scratch; 2965 function = scratch;
2862 } 2966 }
2863 Call(function); 2967 Call(function);
2864 int stack_passed_arguments = (num_arguments <= kRegisterPassedArguments) ? 2968 int stack_passed_arguments = CalculateStackPassedWords(
2865 0 : num_arguments - kRegisterPassedArguments; 2969 num_reg_arguments, num_double_arguments);
2866 if (ActivationFrameAlignment() > kPointerSize) { 2970 if (ActivationFrameAlignment() > kPointerSize) {
2867 ldr(sp, MemOperand(sp, stack_passed_arguments * kPointerSize)); 2971 ldr(sp, MemOperand(sp, stack_passed_arguments * kPointerSize));
2868 } else { 2972 } else {
2869 add(sp, sp, Operand(stack_passed_arguments * sizeof(kPointerSize))); 2973 add(sp, sp, Operand(stack_passed_arguments * sizeof(kPointerSize)));
2870 } 2974 }
2871 } 2975 }
2872 2976
2873 2977
2874 void MacroAssembler::GetRelocatedValueLocation(Register ldr_location, 2978 void MacroAssembler::GetRelocatedValueLocation(Register ldr_location,
2875 Register result) { 2979 Register result) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2926 void CodePatcher::EmitCondition(Condition cond) { 3030 void CodePatcher::EmitCondition(Condition cond) {
2927 Instr instr = Assembler::instr_at(masm_.pc_); 3031 Instr instr = Assembler::instr_at(masm_.pc_);
2928 instr = (instr & ~kCondMask) | cond; 3032 instr = (instr & ~kCondMask) | cond;
2929 masm_.emit(instr); 3033 masm_.emit(instr);
2930 } 3034 }
2931 3035
2932 3036
2933 } } // namespace v8::internal 3037 } } // namespace v8::internal
2934 3038
2935 #endif // V8_TARGET_ARCH_ARM 3039 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/arm/simulator-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698