2013-06-19 10 views
3

안녕하세요 저는 현재 정렬되지 않은 (때때로 때로는) 일련의 부동 소수점을 포함하는 데이터 BLOB를 처리해야하는 프로그램에서 작업하고 있습니다. ARM 코어 텍스 -a8에 대해 gcc 4.6.2로 컴파일 중입니다.GCC에서 배열되지 않은 부동 소수점 액세스를위한 어셈블리를 생성했습니다.

나는 최소한의 예를 쓴 예를 들어 : 내가 생성 된 어셈블리 코드에 대한 질문이 다음 테스트 코드

float aligned[2]; 
float *unaligned = (float*)(((char*)aligned)+2); 

int main(int argc, char **argv) 
{ 
    float f = unaligned[0]; 
    return (int)f; 
} 

컴파일러 (GCC 4.6.2 - 최적화 -O3 포함)의 경우는

을 생산
00008634 <main>: 
    8634: e30038ec   movw   r3, #2284  ; 0x8ec 
    8638: e3403001   movt   r3, #1 
    863c: e5933000   ldr   r3, [r3] 
    8640: edd37a00   vldr   s15, [r3] 
    8644: eefd7ae7   vcvt.s32.f32 s15, s15 
    8648: ee170a90   vmov   r0, s15 
    864c: e12fff1e   bx   lr 

여기서 컴파일러는 데이터 정렬 여부를 알 수 없지만 정렬 된 데이터가 필요한 VLDR을 사용하면 프로그램이 버스 오류로 인해 충돌합니다.

내 실제 질문은 다음과 같습니다.이 컴파일러에서 올바른지 및 내 C++ 코드에서 정렬 처리해야합니까 또는이 컴파일러 버그가 무엇입니까?

값을 액세스하기 전에 복사본을 만들 gcc가 제공하는 현재 해결 방법을 추가 할 수도 있습니다. 트릭은 gcc packed 속성을 가진 float 만 포함하고 struct 포인터를 통해 데이터에 액세스하는 구조체를 정의하는 것입니다. 코드 스 니펫 :

struct FloatWrapper { float f; } __attribute__((packed)); 
const FloatWrapper *x = reinterpret_cast<const FloatWrapper *>(rawX.data()); 
const FloatWrapper *y = reinterpret_cast<const FloatWrapper *>(rawY.data()); 

for (size_t i = 0; i < vertexCount; ++i) { 
    vertices[i].x = x[i].f; 
    vertices[i].y = y[i].f; 
} 
+3

는 C99 표준은 포함 당신이 모든 시나리오에로드 할 주소 주소 등을 연결 한 후 사용할 수있는 것처럼 컴파일러, 찾을 수 없기 때문에 정렬 자신을 돌볼 필요가, 대답은 생각 이 각주 : "단항 * 연산자에 의한 포인터의 역 참조를위한 유효하지 않은 값 중에는 널 포인터, 가리키는 대상의 유형에 맞지 않는 주소가 있습니다 ...". C++ 표준에 비슷한 경고가 포함되어 있다는 것은 의심의 여지가 없습니다. 따라서 프로그램은 기술적으로 정의되지 않았으며 컴파일러는 버그없이 원하는 명령을 자유롭게 생성 할 수 있습니다. –

답변

3

은 당신이 VLDRAlignment fault를 생성, ARM ARM A3.2.1 상태에 관계없이 SCTLR.A 값의 지적했듯이. , 나는 ARM Cortex-A8 TRM 4.2.1으로도 혼란 스러워요

은 내가 코어 텍스 A9에 예를 테스트 한 나는 그러나

# float_align             
[1] + Stopped (signal)  float_align 

을 가지고, 그것은

정렬 규정이 경우를 말한다 가 지정되지 않고 A = 1 인 경우 요소 크기에 맞춰지지 않으면 정렬 오류가 발생합니다.

정렬 한정자가 지정되지 않고 A = 0 인 경우 정렬되지 않은 액세스으로 처리됩니다. ARM ARM 지침에 대한 자세한 테이블과 더 많은 정보를 제공하기 때문에

이, 아마 반 구운 설명이다.

그래서

+0

안녕하세요. 답장을 보내 주셔서 감사합니다. ARMv7-A 및 ARMv7-R 용 ARM 아키텍처 참조 문서 A3.2 Alignment Support/A3.2.1에서 정렬 된 액세스를 지원하지 않는 몇 가지 지침 (VLDR 및 기타 지침)이 있습니다.[참조 설명서 링크] (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406c/index.html) – Jahn

+0

@ Jahn이 대답을 업데이트했습니다. – auselen

+0

auselen을 살펴 주셔서 감사합니다. Pascal에 대한 C (++) 표준에 대한 의견을 더 자세히 살펴보고 결과를 게시합니다. – Jahn