반응형

출처 : http://blog.kmckk.com/archives/4165942.html


요즘 일을 하다가 보니

gnueabihf 라는 툴체인이 쓰이고 있는 것을 발견했다.


예전과 이름이 바껴서 hf가 뭔가하고 찾아봤다.


hf는 Hard Float이라는 의미라고 한다.


FPU사용을 더 효율적이게 해주는 건가보다.


Function Calling Convention이 변경되서 double, float 는 FPU레지스터에 올려서 전달하고 반환 값도 FPU 레지스터를 사용하게 되어 있다고 한다.

지금까지는FPU가 가능했다 하더라고 Soft Float과 호환성 유지를 위해 범용 레지스터를 썼다고 한다.


이 두가지는 섞어 쓸수 없고, 연관 라이브러리에 영향이 있다고 한다.


자세히 알아보면 


우선 툴체인을 설치하고


 $ sudo apt-get install g ++ - arm-linux-gnueabi

 $ sudo apt-get install g ++ - arm-linux-gnueabihf

 

확인해보면


$ ls / usr / bin / arm-linux-gnueabi *

 / usr / bin / arm-linux-gnueabi-addr2line / usr / bin / arm-linux-gnueabihf-gcov

 / usr / bin / arm-linux-gnueabi-ar /usr/bin/arm-linux-gnueabihf-gcov-4.6

 / usr / bin / arm-linux-gnueabi-as / usr / bin / arm-linux-gnueabihf-gprof

 / usr / bin / arm-linux-gnueabi-c ++ filt / usr / bin / arm-linux-gnueabihf-ld

 / usr / bin / arm-linux-gnueabi-cpp /usr/bin/arm-linux-gnueabihf-ld.bfd

 /usr/bin/arm-linux-gnueabi-cpp-4.6 /usr/bin/arm-linux-gnueabihf-ld.gold

 / usr / bin / arm-linux-gnueabi-elfedit / usr / bin / arm-linux-gnueabihf-nm

 / usr / bin / arm-linux-gnueabi-g ++ / usr / bin / arm-linux-gnueabihf-objcopy

 /usr/bin/arm-linux-gnueabi-g++-4.6 / usr / bin / arm-linux-gnueabihf-objdump

 / usr / bin / arm-linux-gnueabi-gcc / usr / bin / arm-linux-gnueabihf-ranlib

 /usr/bin/arm-linux-gnueabi-gcc-4.6 / usr / bin / arm-linux-gnueabihf-readelf

 / usr / bin / arm-linux-gnueabi-gcov / usr / bin / arm-linux-gnueabihf-size

 /usr/bin/arm-linux-gnueabi-gcov-4.6 / usr / bin / arm-linux-gnueabihf-strings

 / usr / bin / arm-linux-gnueabi-gprof / usr / bin / arm-linux-gnueabihf-strip

 / usr / bin / arm-linux-gnueabihf-addr2line / usr / bin / arm-linux-gnueabi-ld

 / usr / bin / arm-linux-gnueabihf-ar /usr/bin/arm-linux-gnueabi-ld.bfd

 / usr / bin / arm-linux-gnueabihf-as /usr/bin/arm-linux-gnueabi-ld.gold

 / usr / bin / arm-linux-gnueabihf-c ++ filt / usr / bin / arm-linux-gnueabi-nm

 / usr / bin / arm-linux-gnueabihf-cpp / usr / bin / arm-linux-gnueabi-objcopy

 /usr/bin/arm-linux-gnueabihf-cpp-4.6 / usr / bin / arm-linux-gnueabi-objdump

 / usr / bin / arm-linux-gnueabihf-elfedit / usr / bin / arm-linux-gnueabi-ranlib

 / usr / bin / arm-linux-gnueabihf-g ++ / usr / bin / arm-linux-gnueabi-readelf

 /usr/bin/arm-linux-gnueabihf-g++-4.6 / usr / bin / arm-linux-gnueabi-size

 / usr / bin / arm-linux-gnueabihf-gcc / usr / bin / arm-linux-gnueabi-strings

 /usr/bin/arm-linux-gnueabihf-gcc-4.6 / usr / bin / arm-linux-gnueabi-strip

 

기존 gnueabi랑 gnueabihf 가 둘다 있는걸 볼 수 있다.


테스트 프로그램






이 프로그램을 두 가지 툴체인으로 컴파일하여 dadd와 fadd 부분의 코드를 비교해 보자.


arm-linux-eabi의 코드


 $ arm-linux-gnueabi-gcc -S -O -o hello_float_gnueabi.s hello_float.c

 

  .align 2

.global dadd

.thumb

.thumb_func

.type dadd % function

 dadd :

@ args = 0, pretend = 0, frame = 0

@ frame_needed = 0, uses_anonymous_args = 0

@ link register save eliminated. 

 fmdrr d6, r0, r1 

 fmdrr d7, r2, r3 

 faddd d6, d6, d7 

 fmrrd r0, r1, d6 

 bx lr

.size dadd.-dadd

.align 2

.global fadd

.thumb

.thumb_func

.type fadd % function

 fadd :

@ args = 0, pretend = 0, frame = 0

@ frame_needed = 0, uses_anonymous_args = 0

@ link register save eliminated. 

 fmsr s14, r0 

 fmsr s15, r1 

 fadds s14, s14, s15 

 fmrs r0, s14 

 bx lr

.size fadd.-fadd


fadd [s | d] 전후에서 범용 레지스터와 FPU 레지스터의 전송을 실시하고 있습니다.


arm-linux-gnueabihf의 코드


 $ arm-linux-gnueabihf-gcc -S -O -o hello_float_gnueabihf.s hello_float.c

 

  .align 2

.global dadd

.thumb

.thumb_func

.type dadd % function

 dadd :

@ args = 0, pretend = 0, frame = 0

@ frame_needed = 0, uses_anonymous_args = 0

@ link register save eliminated. 

 faddd d0, d0, d1 

 bx lr

.size dadd.-dadd

.align 2

.global fadd

.thumb

.thumb_func

.type fadd % function

 fadd :

@ args = 0, pretend = 0, frame = 0

@ frame_needed = 0, uses_anonymous_args = 0

@ link register save eliminated. 

 fadds s0, s0, s1 

 bx lr

.size fadd.-fadd



쓸데없는 전송이 없어져 깔끔해졌습니다.


컴파일 옵션을 자세히 보려면 gcc에 -v 옵션을 쓰면 내부적으로 실행되는 명령과 옵션을 확인할 수 있습니다.


 $ arm-linux-gnueabi-gcc -v -S -O -o hello_float_gnueabi.s hello_float.c Using built-in specs. COLLECT_GCC = arm-linux-gnueabi-gcc COLLECT_LTO_WRAPPER = / usr / lib / gcc / arm-linux- gnueabi / 4.6 / lto-wrapper Target : arm-linux-gnueabi Configured with : ../src/configure -v --with-pkgversion = 'Ubuntu / Linaro 4.6.3-1ubuntu3'--with-bugurl = file : / //usr/share/doc/gcc-4.6/README.Bugs --enable-languages​​ = c, c ++ fortran, objc, obj-c ++ --prefix = / usr --program-suffix = -4.6 --enable- shared --enable-linker-build-id --with-system-zlib --libexecdir = / usr / lib --without-included-gettext --enable-threads = posix --with-gxx-include-dir = / usr / arm-linux-gnueabi / include / c ++ / 4.6.3 --libdir = / usr / lib --enable-nls --enable-clocale = gnu --enable-libstdcxx-debug --enable-libstdcxx-time = yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-multilib --disable-sjlj-exceptions --with-arch = armv7-a --with-float = softfp --with-fpu = vfpv3-d16 --with-mode = thumb --disable-werror --enable-checking = release --build = x86_64-linux-gnu --host = x86_64-linux-gnu --target = arm-linux-gnueabi --program-prefix = arm-linux-gnueabi- --includedir = / usr / arm-linux-gnueabi / include --with-headers = / usr / arm-linux-gnueabi / include --with -libs = / usr / arm-linux-gnueabi / lib Thread model : posix gcc version 4.6.3 (Ubuntu / Linaro 4.6.3-1ubuntu3) COLLECT_GCC_OPTIONS = '- v'-S '-O'-o ' 'hello_float_gnueabi.s'-march = armv7-a '-mfloat-abi = softfp'-mfpu = vfpv3-d16 '-mthumb'/usr/lib/gcc/arm-linux-gnueabi/4.6/cc1 - quiet -v -imultilib. -imultiarch arm-linux-gnueabi hello_float.c -quiet -dumpbase hello_float.c -march = armv7-a -mfloat-abi = softfp -mfpu = vfpv3-d16 -mthumb -auxbase-strip hello_float_gnueabi.s -O -​​version -o hello_float_gnueabi.s -fstack-protector GNU C (Ubuntu / Linaro 4.6.3-1ubuntu3) version 4.6.3 (arm-linux-gnueabi) compiled by GNU C version 4.6.3, GMP version 5.0.2 , MPFR version 3.1.0-p3, MPC version 0.9 GGC heuristics : --param ggc-min-expand = 98 --param ggc-min-heapsize = 127437 ignoring duplicate directory "/ usr / lib / gcc / arm-linux- gnueabi / 4.6 /../../../../ arm-linux-gnueabi / include "ignoring nonexistent directory"/ usr / include / arm-linux-gnueabi "#include"... "search starts here : #include <...> search starts here : /usr/lib/gcc/arm-linux-gnueabi/4.6/include /usr/lib/gcc/arm-linux-gnueabi/4.6/include-fixed / usr / arm- linux-gnueabi / include / usr / include End of search list. GNU C (Ubuntu / Linaro 4.6.3-1ubuntu3) version 4.6.3 (arm-linux-gnueabi) compiled by GNU C version 4.6.3, GMP version 5.0. 2, MPFR version 3.1.0-p3, MPC version 0.9 GGC heuristics : --param ggc-min-expand = 98 --param ggc-min-heapsize = 127437 Compiler executable checksum : 3cfa61caeb3941938bdc401640938509 COMPILER_PATH = / usr / lib / gcc / arm-linux-gnueabi / 4.6 / : / usr / lib / gcc / arm-linux-gnueabi / 4.6 / : / usr / lib / gcc / arm-linux-gnueabi / : / usr / lib / gcc / arm-linux- gnueabi / 4.6 / : / usr / lib / gcc / arm-linux-gnueabi / : / usr / lib / gcc / arm-linux-gnueabi / 4.6 /../../../../ arm-linux- gnueabi / bin / LIBRARY_PATH = / usr / lib / gcc / arm-linux-gnueabi / 4.6 / : / usr / lib / gcc / arm-linux-gnueabi / 4.6 /../../../../ arm -linux-gnueabi / lib /../ lib / : / usr / lib / gcc / arm-linux-gnueabi / 4.6 /../../../../ arm-linux-gnueabi / lib / COLLECT_GCC_OPTIONS = '-v' '-S'-O '-o'hello_float_gnueabi.s '-march = armv7-a' '-mfloat-abi = softfp' '-mfpu = vfpv3-d16'-mthumb ' 


 $ arm-linux-gnueabihf-gcc -v -S -O -o hello_float_gnueabihf.s hello_float.c

 Using built-in specs.

 COLLECT_GCC = arm-linux-gnueabihf-gcc

 COLLECT_LTO_WRAPPER = / usr / lib / gcc / arm-linux-gnueabihf / 4.6 / lto-wrapper

 Target : arm-linux-gnueabihf

 Configured with : ../src/configure -v --with-pkgversion = 'Ubuntu / Linaro 4.6.3-1ubuntu3'--with-bugurl = file : ///usr/share/doc/gcc-4.6/README. Bugs --enable-languages​​ = c, c ++ fortran, objc, obj-c ++ --prefix = / usr --program-suffix = -4.6 --enable-shared --enable-linker-build-id --with- system-zlib --libexecdir = / usr / lib --without-included-gettext --enable-threads = posix --with-gxx-include-dir = / usr / arm-linux-gnueabihf / include / c ++ / 4.6. 3 --libdir = / usr / lib --enable-nls --enable-clocale = gnu --enable-libstdcxx-debug --enable-libstdcxx-time = yes --enable-gnu-unique-object --enable- plugin --enable-objc-gc --enable-multilib --disable-sjlj-exceptions --with-arch = armv7-a --with-float = hard --with-fpu = vfpv3-d16 --with-mode = thumb --disable-werror --enable-checking = release --build = x86_64-linux-gnu --host = x86_64-linux-gnu --target = arm-linux-gnueabihf --program-prefix = arm-linux -gnueabihf- --includedir = / usr / arm-linux-gnueabihf / include --with-headers = / usr / arm-linux-gnueabihf / include --with-libs = / usr / arm-linux-gnueabihf / lib

 Thread model : posix

 gcc version 4.6.3 (Ubuntu / Linaro 4.6.3-1ubuntu3) 

 COLLECT_GCC_OPTIONS = '- v'-S '-O'-o 'hello_float_gnueabihf.s'-march = armv7-a '-mfloat-abi = hard' '-mfpu = vfpv3-d16'-mthumb '

  /usr/lib/gcc/arm-linux-gnueabihf/4.6/cc1 -quiet -v -imultilib. -imultiarch arm-linux-gnueabihf hello_float.c -quiet -dumpbase hello_float.c -march = armv7-a -mfloat-abi = hard -mfpu = vfpv3-d16 -mthumb -auxbase-strip hello_float_gnueabihf.s -O -version -o hello_float_gnueabihf.s -fstack-protector

 GNU C (Ubuntu / Linaro 4.6.3-1ubuntu3) version 4.6.3 (arm-linux-gnueabihf)

compiled by GNU C version 4.6.3, GMP version 5.0.2, MPFR version 3.1.0-p3, MPC version 0.9

 GGC heuristics : --param ggc-min-expand = 98 --param ggc-min-heapsize = 127437

 ignoring duplicate directory "/usr/lib/gcc/arm-linux-gnueabihf/4.6/../../../../arm-linux-gnueabihf/include"

 ignoring nonexistent directory "/ usr / include / arm-linux-gnueabihf"

 #include "..."search starts here :

 #include <...> search starts here :

  /usr/lib/gcc/arm-linux-gnueabihf/4.6/include

  /usr/lib/gcc/arm-linux-gnueabihf/4.6/include-fixed

  / usr / arm-linux-gnueabihf / include

  / usr / include

 End of search list.

 GNU C (Ubuntu / Linaro 4.6.3-1ubuntu3) version 4.6.3 (arm-linux-gnueabihf)

compiled by GNU C version 4.6.3, GMP version 5.0.2, MPFR version 3.1.0-p3, MPC version 0.9

 GGC heuristics : --param ggc-min-expand = 98 --param ggc-min-heapsize = 127437

 Compiler executable checksum : 203eb4988339bc30463f8e81baca2202

 COMPILER_PATH = / usr / lib / gcc / arm-linux-gnueabihf / 4.6 / : / usr / lib / gcc / arm-linux-gnueabihf / 4.6 / : / usr / lib / gcc / arm-linux-gnueabihf / : / usr /lib/gcc/arm-linux-gnueabihf/4.6/:/usr/lib/gcc/arm-linux-gnueabihf/:/usr/lib/gcc/arm-linux-gnueabihf/4.6/../../. ./../arm-linux-gnueabihf/bin/

 LIBRARY_PATH = / usr / lib / gcc / arm-linux-gnueabihf / 4.6 / : / usr / lib / gcc / arm-linux-gnueabihf / 4.6 /../../../../ arm-linux-gnueabihf /lib/../lib/:/usr/lib/gcc/arm-linux-gnueabihf/4.6/../../../../arm-linux-gnueabihf/lib/

 COLLECT_GCC_OPTIONS = '- v'-S '-O'-o 'hello_float_gnueabihf.s'-march = armv7-a '-mfloat-abi = hard' '-mfpu = vfpv3-d16'-mthumb '


기본적으로 -march = armv7-a -mthumb이므로 Thumb2 코드가 생성됩니다. fpu 유형은 vfpv3-d16 그래서 NEON 없이도 움직일 수있게되어 있네요.


덤 (x86_64 및 x86)


$ gcc -v -S -O -o hello_float_native.s hello_float.c


.globl dadd

.type dadd, @function

 dadd :

 .LFB22 :

.cfi_startproc 

 addsd % xmm1 % xmm0 

 ret

.cfi_endproc

 .LFE22 :

.size dadd.-dadd

.globl fadd

.type fadd, @function

 fadd :

 .LFB23 :

.cfi_startproc 

 addss % xmm1 % xmm0 

 ret

.cfi_endproc

 .LFE23 :

.size fadd.-fadd

 

x86_64는 FPU 레지스터 인도로 깔끔하게.


 $ sudo apt-get install g ++ - multilib

 $ gcc -v -m32 -S -O -o hello_float_86.s hello_float.c

.globl dadd

.type dadd, @function

 dadd :

 .LFB22 :

.cfi_startproc 

 fldl 12 (% esp) 

 faddl 4 (% esp) 

 ret

.cfi_endproc

 .LFE22 :

.size dadd.-dadd

.globl fadd

.type fadd, @function

 fadd :

 .LFB23 :

.cfi_startproc 

 flds 8 (% esp) 

 fadds 4 (% esp) 

 ret

.cfi_endproc

 .LFE23 :

.size fadd.-fadd

 

x86이라고 스택 전달.



반응형

'Linux' 카테고리의 다른 글

ubuntu monitoring  (0) 2015.02.10
uImage 만들기 (mkimage)  (0) 2015.01.13
WiredAccessoryManager  (0) 2014.11.28
Posted by Real_G