2016-10-23 9 views
0

에 LLVM-연타를 사용하여 네온 내장 함수를 변환하는 방법 :LLVM-IR을 위해 우리가 컴파일 C 프로그램으로 IR을 생성 할 수 있습니다 연타를 사용하여 86

clang -S -emit-llvm hello.c -o hello.ll 

나는 LLVM-IR, 같은 코드에 고유 네온을 번역하고 싶습니다 이 :이 같은

/* neon_example.c - Neon intrinsics example program */ 
#include <stdint.h> 
#include <stdio.h> 
#include <assert.h> 
#include <arm_neon.h> 
/* fill array with increasing integers beginning with 0 */ 
void fill_array(int16_t *array, int size) 
{ int i; 
    for (i = 0; i < size; i++) 
    { 
     array[i] = i; 
    } 
} 
/* return the sum of all elements in an array. This works by calculating 4 totals (one for each lane) and adding those at the end to get the final total */ 
int sum_array(int16_t *array, int size) 
{ 
    /* initialize the accumulator vector to zero */ 
    int16x4_t acc = vdup_n_s16(0); 
    int32x2_t acc1; 
    int64x1_t acc2; 
    /* this implementation assumes the size of the array is a multiple of 4 */ 
    assert((size % 4) == 0); 
    /* counting backwards gives better code */ 
    for (; size != 0; size -= 4) 
    { 
      int16x4_t vec; 
      /* load 4 values in parallel from the array */ 
      vec = vld1_s16(array); 
      /* increment the array pointer to the next element */ 
      array += 4; 
      /* add the vector to the accumulator vector */ 
      acc = vadd_s16(acc, vec); 
     } 
     /* calculate the total */ 
     acc1 = vpaddl_s16(acc); 
     acc2 = vpaddl_s32(acc1); 
     /* return the total as an integer */ 
     return (int)vget_lane_s64(acc2, 0); 
} 
/* main function */ 
int main() 
{ 
     int16_t my_array[100]; 
     fill_array(my_array, 100); 
     printf("Sum was %d\n", sum_array(my_array, 100)); 
     return 0; 
} 

그러나 그것은 네온 고유 지원하지 않습니다 및 인쇄 오류 메시지 :

/home/user/llvm-proj/build/bin/../lib/clang/4.0.0/include/arm_neon.h:65:24: error: 
     'neon_vector_type' attribute is not supported for this target 
typedef __attribute__((neon_vector_type(8))) float16_t float16x8_t; 
        ^

내 호스트가 x86에 있다고 생각하지만 타겟은 ARM에 있다고 생각합니다. 그리고 how to Cross-compilation using Clang을 llvm-IR (clang 버전은 4.0 우분투 14.04)으로 번역 할 생각이 없습니다. 대상 옵션 명령이나 다른 도구가 유용합니까? SSE와 neon llvm-IR의 차이점은 무엇입니까? ELLCC, 사전 패키지 연타 기반의 툴 체인 (http://ellcc.org)를 사용

답변

1

, 나는 컴파일하고 추가 -mfpu = 네온하여 프로그램을 실행 할 수 있었다 :

[email protected]:~$ ~/ellcc/bin/ecc -target arm32v7-linux -mfpu=neon neon.c 
    [email protected]:~$ ./a. 
    a.exe a.out 
    [email protected]:~$ file a.out 
a.out: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, BuildID[sha1]=613c22f6bbc277a8d577dab7bb27cd64443eb390, not stripped 
[email protected]:~$ ./a.out 
    Sum was 4950 
    [email protected]:~$ 

이가 x86 및 I에 컴파일 QEMU를 사용하여 실행했습니다.

정상적인 clang을 사용하면 ARM에 적합한 -target 옵션도 필요합니다. ELLCC는 약간 다른 타겟 옵션을 사용합니다.

+0

하지만 완료된 ARM 실행 파일로 컴파일 중이지만 요청한대로 LLVM 바이트 코드로 컴파일하지 않습니다. – Notlikethat

+0

@ Notlikethat 당신 말이 맞아요. '-e -emit-llvm –

+0

@RichardPennington을 추가 할 필요가 있으므로'$ ~/ellcc/bin/ecc -target' 다음에 -emit-llvm을 추가하여 ELLCC를 사용하여 llvm-IR을 생성 할 수 있습니까? – Shun