RealView Compilation Tools - ARM...

196
Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IK (ID090708) RealView Compilation Tools 버전 4.0 컴파일러 사용 설명서

Transcript of RealView Compilation Tools - ARM...

Page 1: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

RealView � Compilation Tools버전 4.0

컴파일러 사용 설명서

Copyright © 2002-2009 ARM Limited. All rights reserved.ARM DUI 0205IK (ID090708)

Page 2: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

RealView Compilation Tools컴파일러 사용 설명서

Copyright © 2002-2009 ARM Limited. All rights reserved.

릴리스 정보

이 설명서에서 변경된 내용은 다음과 같습니다.

소유권 고지 사항

이 소유권 고지 사항의 아래 부분에서 달리 명시되지 않는 한 또는 표시가 있는 단어와 로고는 EU, 대한민국 및 기타 국가에서 ARM Limited의 등록 상표 또는 상표입니다. 이 설명서에 언급된 기타 브랜드와 이름은 해당 소유자의 상표일 수 있습니다.

이 설명서에 포함된 전체 또는 일부 정보나 설명된 제품은 해당 저작권 소유자의 사전 서면 승인 없이는 어떤 형태로도 개조되거나 복제될 수 없습니다.

이 설명서에 설명된 제품은 지속적으로 개발 및 개선될 수 있습니다. 이 설명서에 포함된 모든 제품 명세와 해당 사용법은 ARM의 신뢰하에 제공됩니다. 그러나 ARM에서는 상품성 또는 특정 목적에의 적합성을 비롯하여 그 밖의 묵시적이거나 명시적인 모든 보증을 부인합니다.

이 설명서는 제품 사용자를 지원하는 용도로만 만들어졌습니다. ARM은 이 설명서 정보의 사용, 정보의 오류나 누락 또는 제품의 잘못된 사용에 따른 어떠한 손실이나 손상도 책임지지 않습니다.

ARM이라는 단어가 사용되는 경우 “ARM이나 해당하는 자회사”를 의미합니다.

변경 내역

날짜 발행판 기밀 상태 변경 내용

2002년 8월 A 기밀 문서 아님 릴리스 1.2

2003년 1월 B 기밀 문서 아님 릴리스 2.0

2003년 9월 C 기밀 문서 아님 RealView Developer Suite 버전 2.0용 릴리스 2.0.1

2004년 1월 D 기밀 문서 아님 RealView Developer Suite 버전 2.1용 릴리스 2.1

2004년 12월 E 기밀 문서 아님 RealView Developer Suite 버전 2.2용 릴리스 2.2

2005년 5월 F 기밀 문서 아님 RealView Developer Suite 버전 2.2 SP1용 릴리스 2.2

2006년 3월 G 기밀 문서 아님 RealView Development Suite 버전 3.0용 릴리스 3.0

2007년 3월 H 기밀 문서 아님 RealView Development Suite 버전 3.1용 릴리스 3.1

2008년 9월 I 기밀 문서 아님 RealView Development Suite 버전 4.0용 릴리스 4.0

2009년 1월 23일 I 기밀 문서 아님 RealView Development Suite 버전 4.0용 설명서 업데이트

ii Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 3: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

기밀 상태

이 설명서는 기밀 문서가 아닙니다. 이 설명서의 사용, 복사 및 공개 권한은 ARM과 설명서 사용 당사자의 동의하에 라이센스 제한을 받습니다.

액세스 제한 없음은 ARM의 내부 분류입니다.

제품 상태

이 설명서의 정보는 개발이 완료된 제품에 대한 최종 정보입니다.

웹 주소

http://www.arm.com

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. iiiID090708 Non-Confidential, Unrestricted Access

Page 4: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

iv Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 5: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

목차RealView Compilation Tools컴파일러 사용 설명서

서문설명서 개요 .................................................................................................. viii사용자 의견 .................................................................................................. xiii

1 장 소개1.1 ARM 컴파일러 개요 .................................................................................... 1-21.2 NEON 벡터화 컴파일러 개요 ...................................................................... 1-31.3 소스 언어 모드 ............................................................................................ 1-41.4 C 및 C++ 라이브러리 .................................................................................. 1-6

2 장 ARM 컴파일러 시작하기2.1 명령 행 옵션 사용 ........................................................................................ 2-22.2 파일 명명 규칙 .......................................................................................... 2-132.3 헤더 파일 ................................................................................................... 2-152.4 사전 컴파일된 헤더 파일 ........................................................................... 2-182.5 타겟 프로세서 또는 아키텍처 지정 ............................................................ 2-242.6 AAPCS( 프로시저 호출 표준 ) 지정 ........................................................... 2-262.7 링커 피드백 사용 ....................................................................................... 2-282.8 기호 버전 추가 .......................................................................................... 2-31

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. vID090708 Non-Confidential, Unrestricted Access

Page 6: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

3 장 NEON 벡터화 컴파일러 사용3.1 NEON 장치 ................................................................................................. 3-23.2 NEON 용 코드 작성 .................................................................................... 3-33.3 자동 벡터화 사용 ........................................................................................ 3-53.4 예 .............................................................................................................. 3-19

4 장 컴파일러 기능4.1 내장 함수 .................................................................................................... 4-24.2 Pragma ..................................................................................................... 4-144.3 비트 밴딩 .................................................................................................. 4-164.4 스레드 - 지역 스토리지 ............................................................................. 4-204.5 8 바이트 정렬 기능 ................................................................................... 4-21

5 장 코딩 방법5.1 코드 최적화 ................................................................................................. 5-25.2 코드 메트릭스 ........................................................................................... 5-105.3 함수 .......................................................................................................... 5-135.4 함수 인라인 ............................................................................................... 5-185.5 데이터 정렬 ............................................................................................... 5-265.6 부동 소수점 산술 사용 .............................................................................. 5-335.7 0 으로 나누기 오류 트래핑 및 확인 ........................................................... 5-425.8 C99 의 새로운 기능 .................................................................................. 5-47

6 장 진단 메시지6.1 진단 리디렉션 ............................................................................................. 6-26.2 진단 메시지의 심각도 ................................................................................. 6-36.3 진단 메시지의 출력 제어 ............................................................................. 6-46.4 진단 메시지 심각도 변경 ............................................................................. 6-56.5 진단 메시지 표시 안 함 ............................................................................... 6-66.6 진단 메시지의 접두사 문자 ......................................................................... 6-76.7 -W 옵션을 지정하여 경고 메시지를 표시하지 않음 ..................................... 6-86.8 상태 코드 종료 및 종료 메시지 ................................................................... 6-96.9 데이터 흐름 경고 ...................................................................................... 6-10

7 장 인라인 및 임베디드 어셈블러 사용7.1 인라인 어셈블러 ......................................................................................... 7-27.2 임베디드 어셈블러 .................................................................................... 7-197.3 sp, lr 또는 pc 에 액세스하는 레거시 인라인 어셈블러 .............................. 7-297.4 인라인 어셈블리 코드와 임베디드 어셈블리 코드의 차이점 ..................... 7-31

vi Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 7: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

서문

이 서문에서는 RealView Compilation Tools 컴파일러 사용 설명서에 대해 소개합니다. 여기에는 다음 단원이 포함되어 있습니다.

• viii페이지의 설명서 개요

• xiii페이지의 사용자 의견

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. viiID090708 Non-Confidential, Unrestricted Access

Page 8: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

서문

설명서 개요

이 설명서에서는 RVCT(RealView Compilation Tools)에 대한 정보를 제공하고 ARM 컴파일러 및 NEON™ 벡터화 컴파일러에서 지원하는 명령 행 옵션과 컴파일러 관련 기능에 대해 간략히 설명합니다.

대상 독자

이 설명서는 RVCT를 사용하여 응용 프로그램을 만드는 모든 개발자를 위한 것입니다. 여기에서는 독자가 경험 있는 소프트웨어 개발자라고 가정합니다. RVCT와 함께 제공되는 ARM 개발 도구에 대한 개요는 RealView Compilation Tools 핵심 설명서를 참조하십시오.

설명서 사용

이 설명서는 다음 장과 부록으로 구성되어 있습니다.

1장 소개

이 장에서는 ARM 컴파일러, 규칙 표준, C 및 C++ 라이브러리 개요에 대해 설명합니다.

2장 ARM 컴파일러 시작하기

이 장에서는 명령 행 옵션과 컴파일러 관련 기능에 대해 간략히 설명합니다. 또한 컴파일러를 호출하는 방법, 다른 RVCT 도구에 옵션을 전달하는 방법 및 진단 메시지를 제어하는 방법에 대해서도 설명합니다.

3장 NEON 벡터화 컴파일러 사용

이 장에서는 NEON 벡터화 컴파일러에 대한 자습서를 제공하며, NEON 장치에 대한 정보를 제공하고 자동 벡터화 기능을 활용하는 방법에 대해 설명합니다.

4장 컴파일러 기능

이 장에서는 ARM 컴파일러에서 지원하는 내장 함수에 대해 간략히 설명합니다.

5장 코딩 방법

이 장에서는 RVCT의 적절한 프로그래밍 방법에 대해 간략히 설명합니다.

viii Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 9: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

서문

6장 진단 메시지

이 장에서는 RVCT 도구가 생성하는 진단 메시지에 대해 간략히 설명합니다.

7장 인라인 및 임베디드 어셈블러 사용

이 장에서는 ARM 컴파일러에서 제공하는 인라인 및 임베디드 어셈블러에 대해 설명합니다.

이 설명서에서는 ARM 소프트웨어가 기본 위치에 설치되어 있다고 가정합니다. 예를 들어 Windows의 경우 기본 위치는 volume:\Program Files\ARM일 수 있습니다. 예를 들어 install_directory\Documentation\...과 같은 경로 이름을 참조할 때 install_directory는 이 위치를 가리키는 것으로 가정합니다. ARM 소프트웨어를 다른 위치에 설치한 경우에는 이 위치를 변경해야 합니다.

표기 규칙

이 설명서에서는 다음과 같은 표기 규칙을 사용합니다.

monospace 명령, 파일 및 프로그램 이름, 소스 코드와 같이 키보드로 입력할 수 있는 텍스트를 나타냅니다.

monospace 명령 또는 옵션 대신 사용할 수 있는 약어를 나타냅니다. 밑줄이 그어진 텍스트는 전체 명령이나 옵션 이름 대신 입력할 수 있습니다.

monospace italic

명령 및 함수의 인수를 나타냅니다. 인수는 특정 값으로 대체할 수 있습니다.

고정 폭 굵은 글꼴

외부 예제 코드가 사용될 경우 언어 키워드를 나타냅니다.

기울임 글꼴 중요한 사항을 강조 표시하고, 특수 용어를 소개하며, 내부 상호 참조 및 인용 부분을 나타냅니다.

굵은 글꼴 메뉴 이름과 같은 인터페이스 요소를 강조 표시합니다. 적절한 경우 설명 목록의 내용을 강조할 때와 ARM 프로세서 신호 이름을 표시할 때도 사용됩니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. ixID090708 Non-Confidential, Unrestricted Access

Page 10: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

서문

추가 정보

이 단원에는 ARM 계열 프로세서용 코드를 개발하는 데 대한 추가 정보를 제공하는 ARM Limited 및 타사 게시물 목록이 나와 있습니다.

ARM Limited는 설명서의 내용을 정기적으로 업데이트하고 수정합니다. http://infocenter.arm.com/help/index.jsp에서 정오표, 추가 목록 및 ARM FAQ(질문과 대답)를 참조하십시오.

ARM 게시물

이 설명서에는 RVCT와 함께 제공되는 각 개발 도구에 대한 참조 정보가 포함되어 있습니다. 이 제품군에 포함된 다른 게시물은 다음과 같습니다.

• RVCT 핵심 설명서(ARM DUI 0202)

• RVCT Compiler Reference Guide(ARM DUI 0348)

• RVCT 라이브러리 및 부동 소수점 지원 설명서(ARM DUI 0349)

• RVCT 링커 사용 설명서(ARM DUI 0206)

• RVCT 링커 참조 설명서(ARM DUI 0381)

• RVCT 유틸리티 설명서(ARM DUI 0382)

• RVCT 어셈블러 설명서(ARM DUI 0204)

• RVCT 개발자 설명서(ARM DUI 0203)

RVDS 시작 설명서에는 용어집이 제공됩니다.

ARM에서 지원하는 기본 표준, 소프트웨어 인터페이스 및 기타 표준에 대한 자세한 내용은 install_directory\Documentation\Specifications\...를 참조하십시오.

또한 ARM 제품과 관련된 구체적인 내용은 다음 설명서를 참조하십시오.

• ARM 아키텍처 참조 문서, ARMv7-A 및 ARMv7-R edition (ARM DDI 0406)

• ARMv7-M 아키텍처 참조 문서(ARM DDI 0403)

• ARMv6-M 아키텍처 참조 문서(ARM DDI 0419)

• 하드웨어 장치에 대한 ARM 데이터시트 또는 기술 참조 문서

x Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 11: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

서문

기타 게시물

이 설명서에서는 C 또는 C++ 프로그래밍 언어에 대해 설명하지 않습니다. 이 설명서는 C 또는 C++ 프로그래밍을 가르치기 위한 것도 아니고 C 또는 C++ 표준에 대한 참조 설명서도 아닙니다. 프로그래밍에 대한 일반 정보는 다른 설명서에서 찾을 수 있습니다.

다음은 C++ 언어에 대해 설명하는 게시물입니다.

• ISO/IEC 14882:2003, C++ Standard

• Stroustrup, B., The C++ Programming Language(3rd edition, 1997). Addison-Wesley Publishing Company, Reading, Massachusetts. ISBN 0-201-88954-4

다음은 일반 C++ 프로그래밍 정보를 제공하는 설명서입니다.

• Stroustrup, B., The Design and Evolution of C++(1994). Addison-Wesley Publishing Company, Reading, Massachusetts. ISBN 0-201-54330-3

이 설명서는 최초 설계에서 오늘날 사용되는 언어에 이르기까지 C++의 발달 과정을 설명합니다.

• Vandevoorde, D and Josuttis, N.M. C++ Templates: The Complete Guide(2003). Addison-Wesley Publishing Company, Reading, Massachusetts. ISBN 0-201-73484-2

• Meyers, S., Effective C++(1992). Addison-Wesley Publishing Company, Reading, Massachusetts. ISBN 0-201-56364-9

효과적인 C++ 개발에 대해 구체적이고 단순 명료한 가이드라인을 제시합니다.

• Meyers, S., More Effective C++(2nd edition, 1997). Addison-Wesley Publishing Company, Reading, Massachusetts. ISBN 0-201-92488-9

다음은 일반 C 프로그래밍 정보를 제공하는 게시물입니다.

• ISO/IEC 9899:1999, C Standard.

이 표준은 국가별 표준 기관(예: 프랑스의 AFNOR, 미국의 ANSI)에서 찾을 수 있습니다.

• Kernighan, B.W. and Ritchie, D.M., The C Programming Language(2nd edition, 1988). Prentice-Hall, Englewood Cliffs, NJ, USA. ISBN 0-13-110362-8

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. xiID090708 Non-Confidential, Unrestricted Access

Page 12: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

서문

이 설명서는 원래 C 언어 디자이너 및 구현자가 공동 작성했으며, 핵심 ANSI C 내용을 포함하도록 업데이트되었습니다.

• Harbison, S.P. and Steele, G.L., A C Reference Manual(5th edition, 2002). Prentice-Hall, Englewood Cliffs, NJ, USA. ISBN 0-13-089592-X.

매우 상세한 C 참조 안내서로 ANSI C에 대한 유용한 정보를 제공합니다.

• Plauger, P., The Standard C Library(1991). Prentice-Hall, Englewood Cliffs, NJ, USA. ISBN 0-13-131509-9

C 라이브러리에 대한 ANSI 및 ISO 표준을 포괄적으로 다룹니다.

• Koenig, A., C Traps and Pitfalls, Addison-Wesley(1989), Reading, Mass. ISBN 0-201-17928-8

C 프로그래밍에서 가장 빠지기 쉬운 함정을 피하는 법에 대해 설명합니다. 초급, 중급, 고급 모든 수준의 독자에게 유용합니다.

DWARF(Debug With Arbitrary Record Format) 디버그 테이블 표준 및 ELF(Executable and Linking Format) 사양에 대한 최신 정보는 http://www.dwarfstd.org를 참조하십시오.

다음 발행물에서는 ETSI(유럽 통신 표준 협회) 기본 작업에 대한 정보를 제공합니다. 이러한 발행물은 모두 http://www.itu.int의 ITU(국제 전기 통신 연합) 통신국에서 얻을 수 있습니다.

• ETSI Recommendation G.191: Software tools for speech and audio coding standardization

• ITU-T Software Tool Library 2005 User's manual: ETSI Recommendation G.191의 일부로 포함

• ETSI Recommendation G723.1: Dual rate speech coder for multimedia communications transmitting at 5.3 and 6.3 kbit/s

• ETSI Recommendation G.729: Coding of speech at 8 kbit/s using conjugate-structure algebraic-code-excited linear prediction (CS-ACELP)

Texas Instruments 컴파일러 내장 함수에 대한 정보를 제공하는 발행물은 http://www.ti.com의 Texas Instruments에서 사용할 수 있습니다.

xii Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 13: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

서문

사용자 의견

RVCT와 해당 설명서에 대한 의견이 있으시면 ARM Limited에 알려 주시기 바랍니다.

RealView Compilation Tools에 대한 사용자 의견

RVCT와 관련된 문제가 있으시면 해당 공급업체에 문의하십시오. 문의 시 다음 사항을 함께 알려 주시면 보다 신속하고 유용한 답변을 받으실 수 있습니다.

• 사용자 이름 및 회사

• 제품 일련 번호

• 사용 중인 릴리스 정보

• 실행 중인 플랫폼의 세부 사항(예: 하드웨어 플랫폼, 운영 체제 종류 및 버전)

• 문제를 재현하는 작은 독립 실행형 코드 샘플

• 의도한 결과와 실제로 발생한 결과에 대한 명확한 설명

• 사용한 명령(명령 행 옵션 포함)

• 문제를 보여 주는 샘플 출력

• 도구의 버전 문자열(버전 번호 및 빌드 번호 포함)

설명서에 대한 사용자 의견

이 설명서에 오류나 누락이 있으면 다음 사항을 기재하여 [email protected]으로 전자 메일을 보내 주시기 바랍니다.

• 설명서 제목

• 설명서 번호

• 문의 내용에 해당하는 페이지 번호

• 문제에 대한 간략한 설명

추가 및 향상되었으면 하는 기능에 대한 일반적인 제안도 환영합니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. xiiiID090708 Non-Confidential, Unrestricted Access

Page 14: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

서문

xiv Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 15: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

1장 소개

이 장에서는 RVCT와 함께 제공되는 ARM � 컴파일러에 대해 소개합니다. 또한 표준 규칙에 대해 설명하고 RVCT와 함께 제공되는 런타임 라이브러리에 대해 간략히 설명합니다. 이 장은 다음 단원으로 구성되어 있습니다.

• 1-2페이지의 ARM 컴파일러 개요

• 1-3페이지의 NEON 벡터화 컴파일러 개요

• 1-4페이지의 소스 언어 모드

• 1-6페이지의 C 및 C++ 라이브러리

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 1-1ID090708 Non-Confidential, Unrestricted Access

Page 16: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

소개

1.1 ARM 컴파일러 개요

armcc ARM 컴파일러는 표준 C 및 표준 C++ 소스 코드를 ARM 아키텍처 기반 프로세서용 기계어 코드로 컴파일하는 고성능 C 및 C++ 컴파일러로, BSABI(ARM 아키텍처용 기본 표준 응용 프로그램 바이너리 인터페이스()를 사용하여 컴파일하고 DWARF 3 디버그 테이블을 지원하는 ELF 형식으로 출력 개체를 생성합니다. ARM 컴파일러는 EDG(Edison Design Group) 프런트 엔드를 사용합니다.

이전 릴리스에서 RVCT로 업그레이드하는 경우 또는 RVCT를 처음 사용하는 경우 RVCT 핵심 설명서에서 최신 정보를 참조하십시오.

1-2 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 17: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

소개

1.2 NEON 벡터화 컴파일러 개요

NEON™은 ARM 고급 SIMD(Single Instruction, Multiple Data) 확장을 구현한 것입니다.

RVCT는 Cortex-A8 및 Cortex-A9와 같은 NEON 장치가 있는 ARM 프로세서를 타겟으로 하는 ARM 컴파일러의 벡터화 모드인 armcc --vectorize를 제공합니다.

참고

Cortex-A9 타겟용으로 컴파일하려면 RealView Development Suite Profesesional 라이센스가 있어야 합니다.

벡터화는 컴파일러가 C 또는 C++ 코드에서 직접 NEON 벡터 명령을 생성하는 것을 의미합니다.

또한 RVCT는 자동 컴파일러 벡터화의 대체 방법으로 컴파일러 벡터화 단계와 어셈블러 코드 작성 단계 사이에서 SIMD 코드를 생성하는 중간 단계로서 NEON 내장 함수를 제공합니다.

참조:

• 3장 NEON 벡터화 컴파일러 사용

• 4-12페이지의 NEON 내장 함수

• 컴파일러 참조 설명서의 부록 E NEON 지원 사용

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 1-3ID090708 Non-Confidential, Unrestricted Access

Page 18: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

소개

1.3 소스 언어 모드

ARM 컴파일러에는 여러 가지 C 및 C++ 소스 코드를 컴파일하는 데 사용할 수 있는 다음 세 가지 고유한 소스 언어 모드가 있습니다.

ISO C90 ARM 컴파일러는 1990 C 표준 및 추가 목록에서 정의된 대로 C를 컴파일합니다.

컴파일러 옵션 --c90을 사용하면 C90 코드를 컴파일할 수 있습니다. 기본값입니다.

ISO C99 ARM 컴파일러는 1990 C 표준 및 추가 목록에서 정의된 대로 C를 컴파일합니다.

컴파일러 옵션 --c99를 사용하면 C99 코드를 컴파일할 수 있습니다.

ISO C++ ARM 컴파일러는 확장 스트림 및 내보내기 템플릿을 제외하고 2003 표준에 정의된 대로 C++를 컴파일합니다.

컴파일러 옵션 --cpp를 사용하면 C++ 코드를 컴파일할 수 있습니다.

컴파일러는 C 및 C++ 소스 언어에 대한 여러 가지 확장을 지원합니다. 예를 들어 일부 GNU 컴파일러 확장을 지원합니다. 컴파일러에는 소스 언어와의 호환이 강제로 적용되거나 완화되는 여러 가지 모드가 있습니다.

엄격한 모드 엄격한 모드에서는 컴파일러가 소스 언어와 관련된 언어 표준과의 호환이 강제로 적용됩니다.

엄격한 모드에서 컴파일하려면 명령 행 옵션 --strict를 사용하십시오.

GNU 모드 GNU 모드에서는 관련 소스 언어에 대한 모든 GNU 컴파일러 확장을 사용할 수 있습니다.

GNU 모드에서 컴파일하려면 컴파일러 옵션 --gnu를 사용하십시오.

1-4 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 19: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

소개

소스 언어 모드 및 언어 호환에 대한 자세한 내용은 5-47페이지의 C99의 새로운 기능을 참조하십시오. 또한 다음을 참조하십시오.

• 컴파일러 참조 설명서의 1-3페이지의 소스 언어 모드

• 컴파일러 참조 설명서의 1-5페이지의 언어 확장 및 언어 호환

• 컴파일러 참조 설명서의 2-23페이지의 --c90

• 컴파일러 참조 설명서의 2-24페이지의 --c99

• 컴파일러 참조 설명서의 2-32페이지의 --cpp

• 컴파일러 참조 설명서의 2-70페이지의 --gnu

• 컴파일러 참조 설명서의 2-126페이지의 --strict, --no_strict

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 1-5ID090708 Non-Confidential, Unrestricted Access

Page 20: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

소개

1.4 C 및 C++ 라이브러리

RVCT는 다음 런타임 C 및 C++ 라이브러리를 제공합니다.

ARM C 라이브러리

ARM C 라이브러리는 표준 C 함수와 C 및 C++ 라이브러리에서 사용하는 도우미 함수를 제공합니다.

ARM 라이브러리는 다음 규칙을 준수합니다.

• CLIBABI(C Library ABI for the ARM Architecture)

• CPPABI(C++ ABI for the ARM Architecture)

참조:

• 컴파일러 참조 설명서의 1-8페이지의 C 및 C++ 라이브러리

• 라이브러리 설명서의 1-3페이지의 ABI for the ARM Architecture 규격 준수

Rogue Wave Standard C++ Library 버전 2.02.03

Rogue Wave Standard C++ 라이브러리는 Rogue Wave Software, Inc.에서 제공한 대로 cout와 같은 표준 C++ 함수 및 개체를 제공합니다. 또한 여기에는 STL(Standard Template Library)이라는 데이터 구조체와 알고리즘이 포함되어 있습니다.

Rogue Wave 라이브러리에 대한 자세한 내용은 Rogue Wave HTML 설명서 및 Rogue Wave 웹 사이트를 참조하십시오. http://www.roguewave.com

지원 라이브러리

ARM C 라이브러리는 C++ 지원을 사용하도록 하고 다른 아키텍처 및 프로세서용으로 코드를 컴파일하기 위한 추가 구성요소를 제공합니다.

C 및 C++ 라이브러리는 바이너리 형식으로만 제공됩니다. 타겟 시스템의 바이트 순서, 인터워킹 선택 여부 및 부동 소수점 지원 선택 여부와 같은 주요 빌드 옵션의 각 조합에 대한 C 및 C++ 라이브러리의 변형이 있습니다.

라이브러리 설명서의 2장 C 및 C++ 라이브러리를 참조하십시오.

1-6 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 21: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

2장 ARM 컴파일러 시작하기

이 장에서는 ARM 컴파일러 armcc에서 허용하는 명령 행 옵션에 대해 간략히 설명합니다. 또한 컴파일러를 호출하는 방법, 다른 RVCT 도구에 옵션을 전달하는 방법 및 진단 메시지를 제어하는 방법에 대해서도 설명합니다. 이 장은 다음 단원으로 구성되어 있습니다.

• 2-2페이지의 명령 행 옵션 사용

• 2-13페이지의 파일 명명 규칙

• 2-15페이지의 헤더 파일

• 2-18페이지의 사전 컴파일된 헤더 파일

• 2-24페이지의 타겟 프로세서 또는 아키텍처 지정

• 2-26페이지의 AAPCS(프로시저 호출 표준) 지정

• 2-28페이지의 링커 피드백 사용

• 2-31페이지의 기호 버전 추가

컴파일러 참조 설명서를 참조하십시오.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-1ID090708 Non-Confidential, Unrestricted Access

Page 22: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

2.1 명령 행 옵션 사용

명령 행 옵션을 지정하여 컴파일러 작업의 여러 측면을 제어할 수 있습니다.

옵션 유형에 따라 다음 규칙이 적용됩니다.

단일 문자 옵션

모든 단일 문자 옵션이나 인수가 지정된 단일 문자 옵션 앞에 대시(-)를 한 개 추가합니다. 옵션과 인수 사이에 공백을 추가하거나 옵션 바로 뒤에 인수를 지정할 수 있습니다. 예를 들면 다음과 같습니다.

-J 디렉토리

-J 디렉토리

키워드 옵션

모든 키워드 옵션 또는 인수가 있는 키워드 옵션 앞에 이중 대시(--)를 추가합니다. 옵션과 인수 사이에 공백이나 = 문자를 추가해야 합니다. 예를 들면 다음과 같습니다.

--depend=file.d

--depend file.d

선행이 아닌 - 또는 _이 포함된 컴파일러 옵션에는 다음 문자 중 하나를 사용할 수 있습니다. 예를 들어 --force_new_nothrow는 --force-new-nothrow와 같습니다.

이름이 대시로 시작하는 파일을 컴파일하려면 POSIX 옵션(--)을 사용하여 뒤에 나오는 모든 인수를 명령 스위치가 아닌 파일 이름으로 처리하도록 지정합니다. 예를 들어 이름이 -ifile_1인 파일을 컴파일하려면 다음을 사용합니다.

armcc -c -- -ifile_1

2.1.1 ARM 컴파일러 호출

ARM 컴파일러를 호출하는 명령은 다음과 같습니다.

armcc [help-options] [source-language] [search-paths] [project-template-options] [PCH-options] [preprocessor-options] [C++-language] [output-format] [target-options] [debug-options] [code-generation-options] [optimization-options] [diagnostic-options] [additional-checks] [PCS-options] [pass-thru-options] [arm-linux-options] [source]

2-2 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 23: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

이러한 각 옵션에 대한 자세한 내용은 컴파일러 참조 설명서에서 2장 컴파일러 명령 행 옵션을 참조하십시오.

help-options 기본 명령 행 옵션, 컴파일러의 버전 번호 및 컴파일러에서 명령 행을 처리하는 방법을 보여 줍니다.

• 2-73페이지의 --help

• 2-122페이지의 --show_cmdline

• 2-143페이지의 --vsn

source-language 컴파일러에서 허용되는 소스 언어의 변형을 지정합니다.

• 2-23페이지의 --c90

• 2-24페이지의 --c99

• 2-25페이지의 --compile_all_input, --no_compile_all_input

• 2-32페이지의 --cpp

• 2-70페이지의 --gnu

• 2-126페이지의 --strict, --no_strict

• 2-128페이지의 --strict_warnings.

이러한 언어 옵션은 결합할 수 없습니다. 예를 들면 다음과 같습니다armcc --c90 --gnu

search-paths 포함된 파일을 검색할 디렉토리를 지정합니다.

• 2-74페이지의 -Idir[,dir,...]

• 2-81페이지의 -Jdir[,dir,...]

• 2-82페이지의 --kandr_include

• 2-112페이지의 --preinclude=filename

• 2-116페이지의 --reduce_paths, --no_reduce_paths

• 2-129페이지의 --sys_include

이러한 옵션을 같이 지정하는 방법에 대한 자세한 내용은 2-15페이지의 헤더 파일을 참조하십시오.

project-template-options

프로젝트 템플릿 동작을 제어합니다.

• 2-114페이지의 --project=filename, --no_project=filename

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-3ID090708 Non-Confidential, Unrestricted Access

Page 24: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

• 2-117페이지의 --reinitialize_workdir

• 2-146페이지의 --workdir=directory

PCH-options PCH 파일 처리를 제어합니다.

• 2-36페이지의 --create_pch=filename

• 2-106페이지의 --pch

• 2-107페이지의 --pch_dir=dir

• 2-108페이지의 --pch_messages, --no_pch_messages

• 2-108페이지의 --pch_verbose, --no_pch_verbose

• 2-138페이지의 --use_pch=filename

preprocessor-options

사전 처리기 출력 및 매크로 정의와 같은 사전 처리기 동작을 지정합니다.

• 2-23페이지의 -C

• 2-24페이지의 --code_gen, --no_code_gen

• 2-37페이지의 -Dname[(parm-list)][=def]

• 2-54페이지의 -E

• 2-93페이지의 -M

• 2-135페이지의 -Uname

C++-language C++ 컴파일 전용 옵션을 지정합니다.

• 2-3페이지의 --anachronisms, --no_anachronisms

• 2-40페이지의 --dep_name, --no_dep_name

• 2-57페이지의 --export_all_vtbl, --no_export_all_vtbl

• 2-60페이지의 --force_new_nothrow, --no_force_new_nothrow

• 2-69페이지의 --friend_injection, --no_friend_injection

• 2-72페이지의 --guiding_decls, --no_guiding_decls

• 2-75페이지의 --implicit_include, --no_implicit_include

2-4 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 25: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

• 2-76페이지의 --implicit_include_searches, --no_implicit_include_searches

• 2-77페이지의 --implicit_typename, --no_implicit_typename

• 2-99페이지의 --nonstd_qualifier_deduction, --no_nonstd_qualifier_deduction

• 2-104페이지의 --old_specializations, --no_old_specializations

• 2-106페이지의 --parse_templates, --no_parse_templates

• 2-109페이지의 --pending_instantiations=n

• 2-120페이지의 --rtti, --no_rtti

• 2-139페이지의 --using_std, --no_using_std

• 2-141페이지의 --vfe, --no_vfe

output-format 컴파일러 출력 포맷을 지정합니다. 이러한 옵션을 사용하여 객체 파일 및 어셈블리 언어 출력 목록 파일을 생성하고 파일을 종속 파일로 만들 수 있습니다.

• 2-16페이지의 --asm

• 2-22페이지의 -c

• 2-40페이지의 --default_extension=ext

• 2-41페이지의 --depend=filename

• 2-42페이지의 --depend_format=string

• 2-44페이지의 --depend_system_headers, --no_depend_system_headers

• 2-77페이지의 --info=totals

• 2-80페이지의 --interleave

• 2-86페이지의 --list

• 2-94페이지의 --md

• 2-100페이지의 -o filename

• 2-121페이지의 -S

• 2-125페이지의 --split_sections

target-options 타겟 프로세서 또는 아키텍처 및 시작할 때 사용 중인 타겟 명령어 세트를 지정합니다.

• 2-8페이지의 --arm

• 2-24페이지의 --compatible=name

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-5ID090708 Non-Confidential, Unrestricted Access

Page 26: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

• 2-32페이지의 --cpu=list

• 2-32페이지의 --cpu=name

• 2-65페이지의 --fpu=list

• 2-65페이지의 --fpu=name

• 2-129페이지의 --thumb

자세한 내용은 2-24페이지의 타겟 프로세서 또는 아키텍처 지정을 참조하십시오.

half-precision floating-point option

반정밀도 부동 소수점 숫자를 VFPv3 아키텍처에 대한 선택적 확장으로 사용할 수 있도록 합니다.

• 2-62페이지의 --fp16_format=format

debug-options 디버그 테이블의 형식 및 생성을 제어합니다.

• 2-39페이지의 --debug, --no_debug

• 2-39페이지의 --debug_macros, --no_debug_macros

• 2-54페이지의 --dwarf2

• 2-54페이지의 --dwarf3

• 2-69페이지의 -g

code-generation-options

엔디안, 기호 표시 유형 및 정렬 기준과 같은 ARM 컴파일러의 코드 생성 옵션을 지정합니다.

• 2-3페이지의 --alternative_tokens, --no_alternative_tokens

• 2-18페이지의 --bigend

• 2-21페이지의 --bss_threshold=num

• 2-52페이지의 --dllexport_all, --no_dllexport_all

• 2-53페이지의 --dllimport_runtime, --no_dllimport_runtime

• 2-53페이지의 --dollar, --no_dollar

• 2-55페이지의 --enum_is_int

• 2-56페이지의 --exceptions, --no_exceptions

2-6 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 27: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

• 2-57페이지의 --exceptions_unwind, --no_exceptions_unwind

• 2-57페이지의 --export_all_vtbl, --no_export_all_vtbl

• 2-58페이지의 --export_defs_implicitly, --no_export_defs_implicitly

• 2-59페이지의 --extended_initializers, --no_extended_initializers

• 2-73페이지의 --hide_all, --no_hide_all

• 2-90페이지의 --littleend

• 2-90페이지의 --locale=lang_country

• 2-91페이지의 --loose_implicit_cast

• 2-94페이지의 --message_locale=lang_country[.codepage]

• 2-96페이지의 --min_array_alignment=opt

• 2-97페이지의 --multibyte_chars, --no_multibyte_chars

• 2-110페이지의 --pointer_alignment=num

• 2-119페이지의 --restrict, --no_restrict

• 2-123페이지의 --signed_bitfields, --unsigned_bitfields

• 2-123페이지의 --signed_chars, --unsigned_chars

• 2-124페이지의 --split_ldm

• 2-136페이지의 --unaligned_access, --no_unaligned_access

• 2-140페이지의 --vectorize, --no_vectorize

• 2-142페이지의 --vla, --no_vla

• 2-144페이지의 --wchar16

• 2-145페이지의 --wchar32

optimization-options

코드 최적화 수준 및 유형을 제어합니다.

• 2-18페이지의 --autoinline, --no_autoinline

• 2-38페이지의 --data_reorder, --no_data_reorder

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-7ID090708 Non-Confidential, Unrestricted Access

Page 28: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

• 2-61페이지의 --forceinline

• 2-63페이지의 --fpmode=model

• 2-78페이지의 --inline, --no_inline

• 2-83페이지의 --library_interface=lib

• 2-85페이지의 --library_type=lib

• 2-91페이지의 --lower_ropi, --no_lower_ropi

• 2-92페이지의 --lower_rwpi, --no_lower_rwpi

• 2-97페이지의 --multifile, --no_multifile

• 2-102페이지의 -Onum

• 2-104페이지의 -Ospace

• 2-105페이지의 -Otime

• 2-119페이지의 --retain=option

참고

최적화 기준으로 컴파일러에서 생성되는 디버그 정보를 제한할 수 있습니다.

diagnostic-options

컴파일러의 진단 메시지 출력을 제어합니다.

• 2-20페이지의 --brief_diagnostics, --no_brief_diagnostics

• 2-46페이지의 --diag_error=tag[,tag,...]

• 2-47페이지의 --diag_remark=tag[,tag,... ]

• 2-48페이지의 --diag_style={arm|ide|gnu}

• 2-49페이지의 --diag_suppress=tag[,tag,...]

• 2-50페이지의 --diag_suppress=optimizations

• 2-51페이지의 --diag_warning=tag[,tag,...]

• 2-51페이지의 --diag_warning=optimizations

• 2-56페이지의 --errors=filename

• 2-118페이지의 --remarks

• 2-143페이지의 -W

• 2-146페이지의 --wrap_diagnostics, --no_wrap_diagnostics

자세한 내용은 6장 진단 메시지를 참조하십시오.

2-8 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 29: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

command-line option file

추가 명령 행 옵션이 포함된 파일을 지정합니다.

• 2-141페이지의 --via=filename

multiple compilations

기존 빌드 정보가 포함되어 있는 피드백 파일을 지정합니다.

• 2-59페이지의 --feedback=filename

• 2-113페이지의 --profile=filename

PCS-options 사용할 프로시저 호출 표준을 지정합니다.

• 2-4페이지의 --apcs=qualifer...qualifier

자세한 내용은 2-26페이지의 AAPCS(프로시저 호출 표준) 지정을 참조하십시오.

pass-thru-options 다른 RVCT 도구에 옵션을 전달하도록 컴파일러에 지시합니다.

• 2-2페이지의 -Aopt

• 2-82페이지의 -Lopt

arm-linux-options ARM Linux에서 사용할 수 있도록 RVCT를 구성하고 ARM Linux를 타겟으로 하는 응용 프로그램 및 공유 라이브러리를 빌드하기 위한 옵션을 지정합니다.

• 2-12페이지의 --arm_linux_configure

• 2-11페이지의 --arm_linux_config_file=path

• 2-29페이지의 --configure_gcc=path

• 2-30페이지의 --configure_gld=path

• 2-31페이지의 --configure_sysroot=path

• 2-26페이지의 --configure_cpp_headers=path

• 2-27페이지의 --configure_extra_includes=paths

• 2-28페이지의 --configure_extra_libraries=paths

• 2-9페이지의 --arm_linux

• 2-14페이지의 --arm_linux_paths

• 2-121페이지의 --shared

• 2-132페이지의 --translate_gcc

• 2-130페이지의 --translate_g++

• 2-133페이지의 --translate_gld

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-9ID090708 Non-Confidential, Unrestricted Access

Page 30: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

source C 또는 C++ 소스 코드를 포함하는 하나 이상의 텍스트 파일 이름을 제공합니다. 기본적으로 컴파일러는 현재 디렉토리에서 소스 파일을 찾고 출력 파일을 만듭니다.

소스 파일이 어셈블리 파일(확장명이 .s인 파일)이면 컴파일러에서 소스 파일을 처리하도록 ARM 어셈블러를 활성화합니다.

이 옵션은 arm-linux-options에 대해서는 사용되지 않습니다. 다른 모든 옵션에 대해서는 이 옵션을 사용해야 합니다.

ARM 컴파일러는 다음과 같이 하나 이상의 입력 파일을 허용합니다.

armcc -c [options] ifile_1 ... ifile_n

대시(-)가 있는 입력 파일을 지정하면 컴파일러가 stdin에서 읽습니다. 뒤에 나오는 모든 인수를 명령 스위치가 아닌 파일 이름으로 처리하도록 지정하려면 POSIX 옵션(--)을 사용합니다. 자세한 내용은 2-2페이지의 명령 행 옵션 사용을 참조하십시오.

기본 동작

컴파일러 시작 구성은 지정된 명령 행 옵션과 파일 확장명에 따라 컴파일러에 의해 결정됩니다. 명령 행 옵션은 파일 확장명에 의해 결정된 기본 구성을 재정의합니다. 컴파일러 시작 언어는 C 또는 C++일 수 있고 명령어 세트는 ARM 또는 Thumb일 수 있습니다.

명령을 하나만 실행하여 여러 개의 파일을 컴파일하는 경우에는 모든 파일이 같은 유형(C 또는 C++)이어야 합니다. 컴파일러에서 파일 확장명에 따라 언어를 변경하지는 못합니다. 다음 예에서는 지정된 소스 파일의 언어가 서로 다르기 때문에 오류가 생성됩니다.

armcc -c test1.c test2.cpp

파일 확장명이 충돌하는 파일을 지정하는 경우 컴파일러에서 파일 확장명에 관계없이 C 또는 C++에 대해 파일을 컴파일하도록 설정할 수 있습니다. 예를 들면 다음과 같습니다.

armcc -c --cpp test1.c test2.cpp

filename.cmd와 같이 .c로 시작하는 인식할 수 없는 확장명이 나타나면 오류 메시지가 생성됩니다.

2-10 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 31: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

단일 컴파일에 여러 소스 파일을 지정하면 PCH(사전 컴파일된 헤더) 파일 처리가 지원되지 않습니다. PCH 처리를 요청하고 기본 소스 파일을 둘 이상 지정하면 컴파일러에서 오류가 생성되고 컴파일이 중단됩니다.

자세한 내용은 2-18페이지의 사전 컴파일된 헤더 파일을 참조하십시오.

2.1.2 명령 행 옵션 순서 지정

일반적으로 명령 행 옵션은 단일 컴파일러 호출에서 순서에 상관없이 표시할 수 있습니다. 그러나 일부 옵션의 효과는 명령 행에 표시된 순서 및 기타 관련 옵션(예: 접두사 -O가 지정된 최적화 옵션 또는 PCH 옵션)과 결합된 방법에 따라 달라집니다. 자세한 내용은 2-18페이지의 사전 컴파일된 헤더 파일을 참조하십시오.

컴파일러에서는 여러 옵션을 지정할 수 있으며, 여러 옵션이 충돌하는 경우에도 지정이 가능합니다. 즉, 기존 명령 행(예: 매이크파일 또는 via 파일)에 새 옵션을 추가할 수 있습니다.

여기서 옵션은 동일한 명령 행에서 이전 옵션보다 우선하며 마지막에 지정된 옵션이 항상 최우선합니다. 예를 들면 다음과 같습니다.

armcc -O1 -O2 -Ospace -Otime ...

위 명령은 컴파일러에서 다음과 같이 실행됩니다.

armcc -O2 -Otime

컴파일러에서 명령 행을 처리하는 방법을 보려면 --show_cmdline 옵션을 사용하십시오. 이것은 컴파일러가 사용된다는 기본값이 아닌 옵션을 나타냅니다. 모든 via 파일의 내용은 확장됩니다. 여기서 사용한 예제에서는 컴파일러가 armcc -O2 -Otime을 실행하지만 --show_cmdline의 출력에는 -O2가 포함되지 않습니다. -O2는 기본 최적화 수준이며 --show_cmdline에는 기본적으로 적용되는 옵션이 표시되지 않기 때문입니다.

2.1.3 환경 변수를 통한 명령 행 옵션 지정

RVCT40_CCOPT 환경 변수 값을 설정하여 명령행 옵션을 지정할 수 있습니다. 이 구문은 명령 행 구문과 동일합니다. 컴파일러에서 RVCT40_CCOPT의 값을 읽고 명령어 문자열의 맨 앞에 삽입합니다. 즉, RVCT40_CCOPT에 지정된 옵션을 명령 행의 인수로 재정의할 수 있습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-11ID090708 Non-Confidential, Unrestricted Access

Page 32: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

2.1.4 명령 행 옵션 자동 완성

선택적으로 명령 행 옵션의 자동 완성을 요청할 수 있습니다. 이렇게 하려면 자동 완성할 문자 뒤에 점(.)을 삽입하십시오. 자동 완성은 키워드 옵션에만 적용됩니다.

같음(=) 문자 또는 공백 문자로 점과 인수를 구분해야 합니다. 인수 자동 완성은 옵션에는 사용할 수 없습니다.

옵션이 자동 완성되도록 하려면 필요한 모든 문자를 포함시켜야 합니다. 예를 들어 명령 행에서 --diag_su.=223을 사용하여 --diag_suppress=223을 지정합니다.

자세한 내용은 2-2페이지의 명령 행 옵션 사용을 참조하십시오.

2.1.5 파일에서 컴파일러 옵션 읽기

운영 체제에서 명령 행 길이가 제한되는 경우 추가 명령 행 옵션을 컴파일러 옵션이 포함된 파일에 포함시킬 수 있습니다.

--via filename

컴파일러에서 지정된 파일을 열고 추가 명령 행 옵션을 읽습니다.

컴파일러 참조 설명서의 부록 A via 파일 구문를 참조하십시오.

2.1.6 stdin 입력 지정

소스 파일 이름에 빼기 기호(–)를 사용하면 컴파일러에서 stdin의 입력이 사용되도록 지정할 수 있습니다. 기본 컴파일러 모드는 C입니다.

입력을 종료하려면 다음을 누르십시오.

• Ctrl-Z를 누른 다음 Return 키(Microsoft Windows 시스템)

• Ctrl-D(Red Hat Linux 시스템)

다음 두 사항이 모두 해당되는 경우 입력이 종료된 후에 키보드 입력용 어셈블리 목록이 출력 스트림으로 전송됩니다.

• 출력 파일을 지정하지 않는 경우

• -E와 같이 사전 처리기 전용 옵션을 지정하지 않은 경우

-o 옵션을 출력 파일에 지정하면 객체 파일이 작성됩니다. -E 옵션을 지정하면 사전 처리기 출력이 출력 스트림으로 전송됩니다. -o- 옵션을 지정하면 출력이 stdout에 전송됩니다.

2-12 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 33: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

2.2 파일 명명 규칙

ARM 컴파일러는 파일 이름 접미사를 사용하여 컴파일 및 링크 단계에 관련된 파일 클래스를 확인합니다. 컴파일러에서 인식하는 파일 이름 접미사에 대해서는 표 2-1에서 설명합니다.

표 2-1 ARM 컴파일러에서 인식하는 파일 이름 접미사

접미사 설명 사용 참고 정보

.c C 소스 파일 --c90을 의미합니다.

.cpp

.c++

.cxx

.cc

.CC

C++ 소스 파일 --cpp를 의미합니다.

컴파일러는 접미사 .cc 및 .CC를 사용하여 암시적으로 포함할 파일을 식별합니다. 컴파일러 참조 설명서의 5-16페이지의 암시적 포함을 참조하십시오.

.d 종속 목록 파일 .d는 --md 옵션을 사용하는 파일 출력의 기본 출력 파일 이름 접미사입니다.

.h C 또는 C++ 헤더 파일

--cpp --arm

.o

.obj

ARM, Thumb 또는 ELF 형식으로 된 ARM 및 Thumb이 혼합된 객체 파일

.s ARM, Thumb 또는 ARM 및 Thumb이 혼합된 어셈블리 언어 소스 파일

접미사로 .s가 지정된 입력 파일 목록의 파일은 컴파일러가 어셈블러 armasm을 호출하여 어셈블합니다.

.s는 -S 또는 --asm 옵션을 사용하는 파일 출력의 기본 출력 파일 이름 접미사입니다.

.lst 오류 및 경고 목록 파일

.lst는 --list 옵션을 사용하는 파일 출력의 기본 출력 파일 이름 접미사입니다.

.pch 사전 컴파일된 헤더 파일

.pch는 --pch 옵션을 사용하는 파일 출력의 기본 출력 파일 이름 접미사입니다.

.txt 텍스트 파일 .txt는 --interleave 옵션과 함께 -S 또는 --asm 옵션을 사용하는 파일 출력의 기본 출력 파일 이름 접미사입니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-13ID090708 Non-Confidential, Unrestricted Access

Page 34: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

2.2.1 이식성

호스트 간의 이식을 용이하게 하려면 다음 지침을 준수하십시오.

• 파일 이름에 공백이 없어야 합니다. 공백이 포함된 경로 이름이나 파일 이름을 사용해야 하는 경우 경로 및 파일 이름을 큰따옴표(") 또는 작은따옴표(')로 묶으십시오.

• 임베디드 경로 이름은 절대 경로 대신 상대 경로로 만드십시오.

• 임베디드 경로 이름에는 정방향 슬래시(/)를 사용하고 백슬래시(\)를 사용하지 마십시오.

2.2.2 출력 파일

기본적으로 ARM 컴파일러에서 만들어진 출력 파일은 현재 디렉토리에 저장됩니다. 객체 파일은 ARM ELF(Executable and Linkable Format)로 작성됩니다. ELF 설명서는 install_directory\Documentation\Specifications\에 있습니다.

2-14 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 35: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

2.3 헤더 파일

다음과 같은 몇 가지 요소가 #include 헤더 파일 및 소스 파일에 대한 ARM 컴파일러의 검색 방식에 영향을 줍니다.

• 환경 변수 RVCT40INC의 값

• -I 및 -J 컴파일러 옵션

• --kandr_include 및 --sys_include 컴파일러 옵션

• 파일 이름이 절대 파일 이름인지 또는 상대 파일 이름인지 여부

• 파일 이름이 각 괄호로 묶여 있는지 또는 큰따옴표로 묶여 있는지 여부

다음을 참조하십시오.

• 컴파일러 참조 설명서의 2-74페이지의 -Idir[,dir,...]

• 컴파일러 참조 설명서의 2-81페이지의 -Jdir[,dir,...]

• 컴파일러 참조 설명서의 2-82페이지의 --kandr_include

• 컴파일러 참조 설명서의 2-129페이지의 --sys_include

• 컴파일러 참조 설명서의 2-2페이지의 명령 행 옵션

2.3.1 현재 위치

기본적으로 ARM 컴파일러는 Berkeley UNIX 검색 규칙을 사용하기 때문에 현재 위치의 상대 경로에서 소스 파일 및 #include 헤더 파일이 검색됩니다. 현재 위치는 컴파일러에서 현재 처리 중인 소스 또는 헤더 파일이 포함된 디렉토리입니다.

검색 경로 요소의 상대 경로에 파일이 있는 경우 이 파일이 있는 디렉토리가 새로운 현재 위치가 됩니다. 컴파일러에서 해당 파일의 처리가 완료되면 이전의 현재 위치가 복원됩니다. 각 인스턴트에 중첩된 #include 지시어의 스택에 해당하는 현재 위치의 스택이 있습니다. 예를 들어 현재 위치가 include 디렉토리 ...\include이고 컴파일러에서 include 파일 sys\defs.h를 찾고 있는 경우 ...\include\sys\defs.h(있을 경우)가 검색됩니다.

컴파일러에서 defs.h를 처리하기 시작하면 현재 위치는 ...\include\sys가 됩니다. 절대 경로 이름으로 지정되지 않은 defs.h에 포함된 모든 파일은 ...\include\sys의 상대 경로로 검색됩니다.

컴파일러에서 defs.h 처리를 완료하면 원래의 현재 위치 ...\include가 복원됩니다.

컴파일러 옵션 --kandr_include를 지정하여 현재 위치의 스택을 사용하지 않도록 설정할 수 있습니다. 이 옵션을 지정하면 Kernighan 및 Ritchie가 원래 The C Programming Language에서 설명한 검색 규칙이 컴파일러에서 사용됩니다. 이 규

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-15ID090708 Non-Confidential, Unrestricted Access

Page 36: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

칙에서는 루트에 있지 않은 각 사용자 #include가 컴파일되는 소스 파일이 있는 디렉토리의 상대 경로에서 검색됩니다. 컴파일러 참조 설명서의 2-82페이지의 --kandr_include를 참조하십시오.

2.3.2 RVCT40INC 환경 변수

RVCT40INC 환경 변수는 RVCT에서 제공하는 포함된 헤더 및 소스 파일의 위치를 가리킵니다. 이 환경 변수는 변경하지 마십시오. 다른 위치의 파일을 포함하려면 필요에 맞게 -I 및 -J 명령행 옵션을 사용하십시오.

컴파일할 때 -I 옵션으로 지정한 디렉토리가 검색된 후 바로 RVCT40INC로 지정한 디렉토리가 검색됩니다. -J 옵션을 사용하면 RVCT40INC는 무시됩니다.

2.3.3 검색 경로

표 2-2에서는 포함된 헤더 및 소스 파일을 검색할 때 컴파일러에서 사용하는 검색 경로에 영향을 주는 명령행 옵션을 보여 줍니다.

표 2-2:

RVCT40INCdirs

RVCT40INC 환경 변수를 설정한 경우 이 변수에서 지정한 디렉토리 목록

CP 현재 위치

표 2-2 Include 파일 검색 경로

컴파일러 옵션 <include> 검색 순서 "include" 검색 순서

-I 및 -J 모두 사용 안 함

RVCT40INCdirs CP, RVCT40INCdirs

-I RVCT40INCdirs, Idirs CP, Idirs, RVCT40INCdirs

-J Jdirs CP 및 Jdirs

-I 및 -J 모두 사용 Jdirs, Idirs CP, Idirs, Jdirs

--sys_include 영향 없음 검색 경로에서 CP 제거

--kandr_include 영향 없음 Kernighan 및 Ritchie 검색 규칙 사용

2-16 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 37: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

Idirs and Jdirs

-Idirs 및 -Jdirs 컴파일러 옵션으로 지정한 디렉토리

2.3.4 TMP 및 TMPDIR 환경 변수

Windows 플랫폼에서는 환경 변수 TMP를 사용하여 임시 파일에 사용할 디렉토리를 지정합니다.

Hat Linux 플랫폼에서는 환경 변수 TMPDIR을 사용하여 임시 파일에 사용할 디렉토리를 지정합니다. TMPDIR을 설정하지 않으면 일반적으로 기본 임시 디렉토리 /tmp 또는 /var/tmp가 사용됩니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-17ID090708 Non-Confidential, Unrestricted Access

Page 38: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

2.4 사전 컴파일된 헤더 파일

소스 파일을 컴파일할 때 포함된 헤더 파일도 컴파일됩니다. 둘 이상의 소스 파일에 헤더 파일이 포함되어 있는 경우에는 각 소스 파일이 컴파일될 때 다시 컴파일됩니다. 또한 여러 코드 행이 삽입된 헤더 파일을 포함할 수는 있지만 이런 헤더 파일이 포함된 기본 소스 파일은 비교적 작습니다. 그렇기 때문에, 헤더 파일을 사전 컴파일하여 헤더 파일 세트를 다시 컴파일하지 않는 것이 좋습니다. 이러한 파일을 사전 컴파일된 헤더(PCH)라고 합니다.

기본적으로 컴파일러에서 PCH 파일을 만들 때 다음과 같은 작업을 수행합니다.

• 기본 소스 파일 이름에서 접미사를 .pch로 바꿉니다.

• 기본 소스 파일과 동일한 디렉토리에 파일을 생성합니다.

참고

단일 컴파일에 여러 소스 파일을 지정하는 경우 PCH 처리가 지원되지 않습니다. PCH 처리를 요청하고 기본 소스 파일을 둘 이상 지정하면 컴파일러에서 오류가 생성되고 컴파일이 중단됩니다.

참고

PCH 파일을 사용할 수 있는 경우에도 이 파일을 컴파일러가 사용한다고 가정해서는 안 됩니다. RHE3 및 Vista의 주소 공간 임의화와 같은 시스템 구성 문제로 인해 컴파일러가 PCH 파일을 사용할 수 없는 경우도 있기 때문입니다.

ARM 컴파일러에서는 자동으로 헤더 파일을 사전 컴파일하거나 사용자가 사전 컴파일을 제어할 수 있습니다. 다음을 참조하십시오.

• 자동 PCH 처리

• 2-21페이지의 수동 PCH 처리

• 2-23페이지의 PCH 처리 중 메시지 출력 제어

• 2-23페이지의 성능 문제.

2.4.1 자동 PCH 처리

--pch 명령- 행 옵션을 사용하여 자동 PCH 처리를 사용할 수 있습니다. 즉, 컴파일러에서 자동으로 적절한 PCH 파일을 찾고 파일을 찾은 다음 읽습니다. 파일을 찾지 못하면 컴파일러에서 이후의 컴파일에 사용할 파일을 만듭니다.

2-18 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 39: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

컴파일러에서 PCH 파일을 만들면 기본 소스 파일 이름에서 접미사를 .pch로 바꿉니다. --pch_dir 옵션을 지정하지 않으면 PCH 파일이 기본 소스 파일의 디렉토리에 생성됩니다.

자세한 내용은 2-10페이지의 명령 행 옵션 순서 지정을 참조하십시오.

헤더 중단 지점

PCH 파일에는 헤더 중단 지점 앞에 오는 모든 코드의 스냅샷이 포함되어 있습니다. 일반적으로 헤더 중단 지점은 사전 처리 지시어에 속하지 않는 기본 소스 파일의 첫 번째 토큰입니다. 다음 예에서 헤더 중단 지점은 int이고 PCH 파일에는 xxx.h 및 yyy.h의 포함을 보여 주는 스냅샷이 포함되어 있습니다.

#include "xxx.h"#include "yyy.h"int i;

참고

#pragma hdrstop으로 헤더 중단 지점을 직접 지정할 수 있습니다. 헤더 중단 지점은 사전 처리 지시어에 속하지 않는 첫 번째 토큰 앞에 위치해야 합니다. 이 예에서는 int 앞에 배치하십시오. 자세한 내용은 2-22페이지의 PCH 처리 제어를 참조하십시오.

PCH 파일 생성에 영향을 주는 조건

사전 처리기 토큰이 아닌 첫 번째 토큰 또는#pragma hdrstop이 #if 블록에 있으면 헤더 중단 지점은 가장 바깥쪽 #if입니다. 예를 들면 다음과 같습니다.

#include "xxx.h"#ifndef YYY_H#define YYY_H 1#include "yyy.h"#endif#if TESTint i;#endif

이 예에서 사전 처리 지시어에 속하지 않는 첫 번째 토큰은 int이지만 헤더 중단 지점은 이 토큰이 속한 #if 블록의 시작 부분입니다. PCH 파일은 xxx.h 포함을 반영하고 조건부로 YYY_H의 정의와 yyy.h의 포함을 반영합니다. #if TEST에서 생성된 상태는 포함되지 않습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-19ID090708 Non-Confidential, Unrestricted Access

Page 40: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

헤더 중단 지점 및 앞에 오는 코드(주로 헤더 파일)가 다음 조건을 충족하는 경우에만 PCH 파일이 생성됩니다.

• 헤더 중단 지점은 파일 범위 내에 있어야 합니다. 헤더 파일에서 생성된 닫히지 않은 범위 내에 있을 수 없습니다. 예를 들어 다음 경우에 PCH 파일이 생성되지 않습니다.

// xxx.hclass A{

// xxx.c#include "xxx.h"int i;

};

• 헤더 중단 지점은 헤더 파일 내에서 시작된 선언 내에 있으면 안 됩니다. 또한 C++에서는 링키지 지정 선언 목록의 일부가 아니어야 합니다. 예를 들어 다음 경우에 헤더 중단 지점은 int이지만 새 선언의 시작 부분이 아니므로 PCH 파일이 생성되지 않습니다.

// yyy.hstatic// yyy.c#include "yyy.h"int i;

• 헤더 중단 지점은 #if 블록 또는 헤더 파일 내에서 시작된 #define 안에 있으면 안 됩니다.

• 헤더 중단 지점 이전 처리에 오류가 없어야 합니다.

참고

PCH 파일을 다시 사용하는 경우 경고 및 기타 진단이 생성되지 않습니다.

• 사전 정의된 매크로 __DATE__ 또는 __TIME__에 대한 참조가 없어야 합니다.

• #line 사전 처리 지시어의 인스턴스가 없어야 합니다.

• #pragma no_pch가 없어야 합니다.

• 헤더 중단 지점 앞의 코드에 사전 컴파일된 헤더와 연결된 오버헤드가 유효하도록 충분한 선언이 삽입되어야 합니다.

둘 이상의 PCH 파일이 지정된 컴파일에 적용될 수 있습니다. 이런 경우 가장 큰 파일, 즉 기본 소스 파일에서 가장 큰 사전 처리 지시어를 포함하는 파일이 사용됩니다. 예를 들어 기본 소스 파일은 다음으로 시작할 수 있습니다.

2-20 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 41: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

#include "xxx.h"#include "yyy.h"#include "zzz.h"

xxx.h에 대한 PCH 파일 하나와 xxx.h 및 yyy.h에 대한 두 번째 PCH 파일이 있으면 둘 다 현재 컴파일에 적용되는 것으로 간주되어 두 번째 PCH 파일이 선택됩니다. 또한 첫 번째 두 헤더에 대해 PCH 파일을 읽어서 세 번째 헤더를 컴파일한 후에도 세 헤더 모두에 대해 새 PCH 파일이 생성될 수도 있습니다.

자동 PCH 처리 모드에서는 다음과 같은 상황인 경우 컴파일러에서 PCH 파일이 오래되어 삭제하도록 표시합니다.

• PCH 파일에 하나 이상의 오래된 헤더 파일이 있으며 해당 헤더 파일로 인해 현재 컴파일에서 사용할 수 없는 경우

• xxx.pch와 xxx.pch와 같이 PCH 파일 이름이 컴파일되는 소스 파일과 기본 이름이 같지만 현재 컴파일에 사용할 수 없는 경우(예를 들어 다른 명령행 옵션을 사용했기 때문에)

이것은 일반적인 경우들을 나타냅니다. 필요하면 다른 PCH 파일은 삭제해야 합니다.

2.4.2 수동 PCH 처리

PCH 파일의 이름과 위치 및 PCH 처리가 필요한 헤더 파일 부분을 지정할 수 있습니다.

PCH 파일 이름 및 위치 지정

다음 명령 행 옵션을 사용하여 PCH 파일의 이름과 위치를 지정할 수 있습니다.

• --create_pch=filename

• --use_pch=filename

• --pch_dir=directory

파일 이름이 절대 경로 이름이 아닌 경우 --create_pch 또는 --create_pch를 --pch_dir 옵션으로 사용하면 표시된 파일 이름이 디렉토리 이름 끝에 추가됩니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-21ID090708 Non-Confidential, Unrestricted Access

Page 42: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

명령 행 옵션 순서 지정

컴파일러에서 위의 옵션 세 가지를 동시에 동일한 명령 행에서 사용할 수는 없습니다. 이 옵션 중 둘 이상이 지정되는 경우에는 다음 규칙이 적용됩니다.

• --use_pch는 --pch 앞에 옵니다.

• --create_pch는 다른 모든 PCH 옵션보다 우선적으로 사용됩니다.

자동 PCH 처리의 특징 대부분은 이러한 모드 중 하나에 적용됩니다. 예를 들어 헤더 중단 지점 및 PCH 파일 적용 가능성이 같은 방식으로 결정됩니다.

PCH 처리 제어

다음 pragma를 사용하여 PCH 처리가 필요한 헤더 파일 부분을 지정할 수 있습니다.

• 기본 소스 파일에서 #pragma hdrstop 지시어를 사용하여 사전 처리 지시어에 속하지 않는 첫 번째 토큰 앞에 수동 헤더 중단 지점을 삽입하십시오.

그러면 사전 컴파일이 필요한 헤더 파일 세트가 끝나는 위치를 지정할 수 있습니다. 예를 들면 다음과 같습니다.

#include "xxx.h"#include "yyy.h"#pragma hdrstop#include "zzz.h"

이 예제에서 PCH 파일에 xxx.h 및 yyy.h의 처리 상태는 포함되지만 zzz.h의 처리 상태는 포함되지 않습니다. #pragma hdrstop 다음에 나오는 정보를 기반으로 다른 PCH 파일이 생성되지 않도록 하려는 경우에 유용합니다.

• #pragma no_pch 지시어를 사용하여 소스 파일에 대해 PCH 처리를 하지 않습니다.

참고

자동 PCH 처리를 사용하는 경우에도 이 pragma를 사용할 수 있습니다.

자세한 내용은 4-14페이지의 Pragma를 참조하십시오.

2-22 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 43: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

2.4.3 PCH 처리 중 메시지 출력 제어

컴파일러에서 PCH 파일을 생성하거나 사용할 때 다음 메시지가 표시됩니다.

test.c: creating precompiled header file test.pch

명령 행 옵션 --no_pch_messages를 지정하여 이 메시지가 표시되지 않도록 할 수 있습니다.

--pch_verbose 옵션을 사용하면 컴파일러에서 사용하려고 시도하지만 사용할 수는 없는 각 PCH 파일에 대해 파일을 사용할 수 없는 이유를 설명하는 메시지가 표시됩니다.

2.4.4 성능 문제

일반적으로 아주 큰 헤더 파일의 경우에도 일반적으로 PCH 파일을 생성하고 읽는 오버헤드는 작으며, 생성된 PCH 파일이 사용되지 않는 경우도 여기에 포함됩니다. 일반적으로 PCH 파일을 사용하면 컴파일 시간이 상당히 감소합니다. 그러나 PCH 파일 크기는 250KB에서 몇 MB까지 되기 때문에 일반적으로 여러 개의 PCH 파일을 생성하지는 않습니다.

PCH 처리가 적합하지 않은 경우도 있을 수 있습니다. 일관되지 않은 초기 시퀀스가 있는 사전 처리 지시어를 포함하는 임의의 파일 세트를 예로 들 수 있습니다.

여러 소스 파일에서 동일한 PCH 파일을 공유하는 경우에는 PCH 처리가 유용합니다. 많이 공유할수록 사용되는 디스크 공간 크기가 줄어듭니다. 공유를 통해 컴파일 시간은 크게 줄어들면서도 PCH 파일의 단점이 큰 크기의 문제점은 최소화됩니다.

그러므로 헤더 파일의 사전 컴파일을 최대한 활용하려면 공통으로 사용되는 헤더 파일 내에 있는 소스 파일의 #include 섹션 또는 그룹 #include 지시어의 순서를 다시 지정해야 할 수 있습니다.

실행하는 환경 및 프로젝트에 따라 요구 사항이 달라집니다. 그러나 PCH 지원을 최대한 사용하려면 일부를 시험적으로 구현해야 할 필요가 있으며 소스 코드를 조금 변경해야 할 수도 있습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-23ID090708 Non-Confidential, Unrestricted Access

Page 44: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

2.5 타겟 프로세서 또는 아키텍처 지정

RVCT에서는 ARM NEON™ 기술을 포함하여 ARMv4 이후의 모든 ARM 아키텍처를 지원합니다. ARMv4 이전의 모든 아키텍처 이름은 현재 사용되지 않으며 더 이상 지원되지 않습니다.

타겟 프로세서 또는 아키텍처를 지정하면 컴파일러에서 선택한 프로세서나 아키텍처 전용 추가 기능을 이용할 수 있습니다. --cpu 및 --fpu 옵션을 사용하면 이러한 기능을 사용하도록 설정할 수 있습니다.

또한 --arm 또는 --thumb 옵션을 사용하여 시작 명령어 세트를 지정할 수도 있습니다.

다음을 참조하십시오.

• 2-25페이지의 NEON 기술

• 5-4페이지의 타겟 CPU 선택

• 개발자 설명서의 5장 ARM과 Thumb의 인터워킹

또한 컴파일러 참조 설명서에서 다음을 추가로 참조하십시오.

• 2-8페이지의 --arm

• 2-32페이지의 --cpu=list

• 2-32페이지의 --cpu=name

• 2-65페이지의 --fpu=list

• 2-65페이지의 --fpu=name

• 2-129페이지의 --thumb

2-24 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 45: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

2.5.1 NEON 기술

NEON 기술이라고도 하는 SIMD(ARM Advanced Single Instruction Multiple Data) Extension은 멀티미디어 및 신호 처리 응용 프로그램의 성능을 향상시키기 위해 ARM에서 개발한 64/128비트 복합 SIMD 아키텍처입니다. NEON은 프로세서의 일부로 구현되지만 자체 실행 파이프라인이 있으며 ARM 레지스터 뱅크와는 별개의 레지스터 뱅크가 있습니다. 주요 기능으로는 정렬 및 정렬되지 않은 데이터 액세스, 정수 지원, 고정 소수점 및 단정밀도 부동 소수점 데이터 유형, ARM 코어와의 밀접한 결합, 다중 뷰가 지원되는 큰 레지스터 파일 등이 있습니다. NEON 명령어는 ARM과 Thumb-2 모두에서 사용할 수 있습니다.

ARM 컴파일러에서는 NEON 장치에 장착된 Cortex™ 프로세서를 지원합니다. NEON 명령어를 생성하려면 명령 행에 NEON 기술이 포함된 Cortex 프로세서를 지정해야 합니다(예: --cpu=Cortex-A8). ARMv7 이전 버전의 아키텍처에 대해서는 NEON이 지원되지 않습니다.

컴파일러 참조 설명서의 부록 E NEON 지원 사용을 참조하십시오.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-25ID090708 Non-Confidential, Unrestricted Access

Page 46: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

2.6 AAPCS(프로시저 호출 표준) 지정

AAPCS(ARM 아키텍처용 프로시저 호출 표준)는 BSABI(ARM 아키텍처용 기본 표준 응용 프로그램 바이너리 인터페이스) 사양에 포함되어 있습니다. AAPCS를 준수하는 코드를 작성하여 별도로 컴파일되고 어셈블된 모듈을 함께 사용할 수 있습니다.

다음을 참조하십시오.

• 인터워킹 한정자

• 위치 독립 한정자

• 2-24페이지의 타겟 프로세서 또는 아키텍처 지정

• install_directory\Documentation\Specifications\....에 있는 ARM 아키텍처용 프로시저 호출 표준 사양(aapcs.pdf)

2.6.1 인터워킹 한정자

이러한 --apcs 한정자는 인터워킹을 제어합니다.

다음을 참조하십시오.

• 컴파일러 참조 설명서의 2-4페이지의 --apcs=qualifer...qualifier

• 개발자 설명서의 5장 ARM과 Thumb의 인터워킹

• 링커 사용 설명서의 3장 기본 링커 기능 사용

2.6.2 위치 독립 한정자

이러한 --apcs 한정자는 위치 독립성을 제어할 뿐 아니라 재진입 및 스레드 안전 코드에도 영향을 줍니다.

다음을 참조하십시오.

• 컴파일러 참조 설명서의 2-4페이지의 --apcs=qualifer...qualifier

• 2-27페이지의 위치 독립적인 코드 및 데이터에 대한 제한

• 라이브러리 설명서의 2-5페이지의 재진입 및 스레드 안전성 코드 작성

• 링커 참조 설명서의 4장 BPABI 및 SysV 공유 라이브러리와 실행 가능 파일

2-26 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 47: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

위치 독립적인 코드 및 데이터에 대한 제한

/ropi, /rwpi 또는 /fpic로 코드를 컴파일하는 경우 제한이 있습니다. 주요 제한은 다음과 같습니다.

• C++를 컴파일할 때 --apcs /ropi를 지정할 수 없습니다. /ropi를 지정하여 C++의 C 하위 세트만 컴파일할 수 있습니다.

• 올바른 C인 일부 구문이 --apcs=/ropi 또는 --apcs=/rwpi에 대해 컴파일할 때 작동하지 않습니다. 예를 들면 다음과 같습니다.

int i; // rwint *p1 = &i; // this static initialization does not work // with --apcs=/rwpi --no_lower_rwpiextern const int ci; // roconst int *p2 = &ci; // this static initialization does not work // with --apcs=/ropi

그러나 이러한 정적 초기화를 사용할 수 있도록 설정하려면 --lower_rwpi 및 --lower_ropi 옵션을 사용하십시오.

이 코드를 컴파일하려면 다음을 입력하십시오.

armcc --apcs=/rwpi/ropi --lower_ropi

이것이 기본값이므로 --lower_rwpi를 지정하지 않아도 됩니다.

• C++를 컴파일할 때 --apcs=/fpic를 지정할 수 없습니다. 여기서 가상 테이블 함수 및 typeinfo가 읽기- 쓰기 영역에 배치되어 PC 위치에 상대 위치에서 액세스할 수 있습니다.

• --apcs=/fpic를 사용하면 컴파일러에서 __declspec(dllexport)이 표시된 함수와 데이터만 내보냅니다.

• --no_hide_all을 사용하는 경우, 모든 extern 변수와 함수가 __declspec(dll*)을 사용하지 않으면 컴파일러가 이들 변수 및 함수에 대해 STV_DEFAULT 표시를 사용합니다. 컴파일러에서는 STV_DEFAULT 표시를 통해 함수 자동 인라인을 비활성화합니다.

예를 들어 System V 또는 ARM Linux 공유 라이브러리를 빌드할 경우 --no_hide_all과 --apcs /fpic를 함께 사용합니다.

__declspec 키워드에 대한 자세한 내용은 컴파일러 참조 설명서에서 4-26페이지의 __declspec 속성을 참조하십시오.

기호 표시에 대한 자세한 내용은 링커 참조 설명서에서 4-4페이지의 기호 표시 유형을 참조하십시오.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-27ID090708 Non-Confidential, Unrestricted Access

Page 48: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

2.7 링커 피드백 사용

링커에서는 다음을 수행할 수 있도록 하는 피드백을 제공합니다.

• 사용하지 않는 함수의 효율적 제거

• 인터워킹에 필요한 컴파일 감소

2.7.1 사용하지 않는 함수 제거

다음과 같은 상황에서 사용하지 않는 함수 코드가 발생할 수 있습니다.

• 소스 코드에 더 이상 사용하지 않는 레거시 함수가 있는 경우. 소스 코드에서 사용하지 않는 함수 코드를 수동으로 제거하지 않고 링커 피드백을 사용하여 최종 이미지에서 사용하지 않는 객체 코드를 자동으로 제거할 수 있습니다.

• 함수가 인라인된 경우. 인라인된 함수가 static으로 선언되지 않은 경우에 라인 외부 함수 코드가 계속 객체 파일에 있지만 더 이상 이 코드를 호출하지 않습니다.

사용하지 않는 함수를 객체 파일에서 제거하려면

1. 소스 코드를 컴파일합니다.

2. 링커 옵션 --feedback=filename을 사용하여 피드백 파일을 만듭니다. 기본적으로 사용하지 않는 함수를 제거하기 위한 형식의 피드백이 생성됩니다.

3. 컴파일러 옵션 --feedback=filename을 사용하여 피드백 파일을 컴파일러에 제공합니다.

컴파일러는 링커에서 생성한 피드백 파일을 사용하여 이후에 링커가 사용되지 않는 함수를 폐기할 수 있는 방식으로 소스 코드를 컴파일합니다.

참고

링커 피드백을 최대한 이용하려면 컴파일 및 링크 작업 전체를 적어도 두 번 실행합니다. 그러나 대개 이전 빌드의 피드백을 사용하는 단일 컴파일 및 링크로도 효과를 볼 수 있습니다.

피드백 파일이 없는 경우에도 --feedback=filename 옵션을 지정할 수 있습니다. 그러면 피드백 파일의 유무에 상관없이 같은 빌드와 매이크파일을 사용할 수 있습니다. 예를 들면 다음과 같습니다.

2-28 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 49: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

armcc -c --feedback=unused.txt test.c -o test.oarmlink --feedback=unused.txt test.o -o test.axf

응용 프로그램을 처음으로 빌드할 때 일반적으로 컴파일은 수행되지만 컴파일러에서는 지정한 피드백 파일을 읽을 수 없음(파일이 없으므로)을 경고합니다. 그러면 링크 명령으로 피드백 파일이 만들어 지고 이미지도 빌드됩니다. 이후의 각 컴파일 단계에서 이전 링크 단계의 피드백 파일을 사용하여 확인된 사용되지 않는 모든 함수를 제거합니다.

다음을 참조하십시오.

• 컴파일러 참조 설명서의 2-59페이지의 --feedback=filename

• 링커 참조 설명서의 2-25페이지의 --feedback_type=type

• 링커 사용 설명서의 3-14페이지의 피드백

2.7.2 인터워킹에 필요한 컴파일 감소

참고

인터워킹에 필요한 컴파일 감소 작업은 ARMv4T 아키텍처에만 해당되며, ARMv5T 이상 프로세서에서는 성능 저하 없이 인터워킹을 수행할 수 있습니다.

Thumb 상태에서 ARM 함수가 호출되거나 ARM 상태에서 Thumb 함수가 호출되면 링커에서는 이를 감지합니다. 링커에서 보낸 피드백을 사용하면 인터워킹 컨텍스트에서는 사용되지 않는 인터워킹용 함수를 컴파일하지 않을 수 있습니다.

인터워킹에 필요한 컴파일을 줄이려면

1. 소스 코드를 컴파일합니다.

2. 링커 옵션 --feedback=filename 및 --feedback_type=iw를 사용하여 인터워킹 지원이 필요한 함수를 보고하는 피드백 파일을 만듭니다.

3. 컴파일러 옵션 --feedback=filename을 사용하여 피드백 파일을 컴파일러에 제공합니다.

컴파일러는 링커에서 생성한 피드백 파일을 사용하여 이후에 컴파일러가 인터워킹 컨텍스트에서는 사용되지 않는 함수를 인터워킹용으로 컴파일하지 않도록 하는 방식으로 소스 코드를 컴파일합니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-29ID090708 Non-Confidential, Unrestricted Access

Page 50: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

참고

링커 피드백 파일을 사용하기 직전에 항상 전체 Clean build를 수행하십시오. 그러면 피드백 파일을 생성하는 데 사용된 소스 코드를 통해 피드백 파일을 최신 상태로 유지할 수 있습니다.

다음을 참조하십시오.

• 컴파일러 참조 설명서의 2-59페이지의 --feedback=filename

• 링커 참조 설명서의 2-25페이지의 --feedback_type=type

• 링커 사용 설명서의 3-14페이지의 피드백

2-30 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 51: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

2.8 기호 버전 추가

컴파일러 및 링커에서는 GNU 확장 기호 버전 관리 모델을 지원합니다.

C 또는 C++ 코드에서 기호 버전이 있는 함수를 생성하려면 어셈블러 레이블 GNU 확장을 사용하여 함수 기호의 이름을 function@@ver(function의 기본 ver인 경우) 또는 function@ver(function의 기본 버전이 아닌 ver의 경우)로 변경해야 합니다.

예를 들어 기본 버전을 정의하려면 다음 명령어를 실행합니다.

int new_function(void) __asm__("versioned_fun@@ver2");int new_function(void){ return 2;}

기본 버전 이외의 버전을 정의하려면 다음 명령어를 실행합니다.

int old_function(void) __asm__("versioned_fun@ver1");int old_function(void){ return 1;}

다음을 참조하십시오.

• 컴파일러 참조 설명서의 3-22페이지의 어셈블러 레이블

• 링커 사용 설명서의 4-15페이지의 기호 버전 관리

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 2-31ID090708 Non-Confidential, Unrestricted Access

Page 52: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

ARM 컴파일러 시작하기

2-32 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 53: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

3장 NEON 벡터화 컴파일러 사용

이 장에서는 NEON™ 장치에 대한 정보를 제공하고 자동 벡터화 기능을 활용하는 방법에 대해 설명합니다. 여기에는 다음 단원이 포함되어 있습니다.

• 3-2페이지의 NEON 장치

• 3-3페이지의 NEON용 코드 작성

• 3-5페이지의 자동 벡터화 사용

• 3-7페이지의 성능 향상

• 3-19페이지의 예

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 3-1ID090708 Non-Confidential, Unrestricted Access

Page 54: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

3.1 NEON 장치

NEON 장치는 16바이트 정보를 보유하는 벡터 레지스터를 총 32개 제공합니다. 이러한 16바이트 레지스터는 NEON 장치에서 병렬로 작동할 수 있습니다. 예를 들어 8개의 16비트 정수를 8개의 다른 16비트 정수에 추가하여 8개의 16비트를 만들 수 있는 명령어를 한 벡터에 추가할 수 있습니다.

NEON 장치는 32비트 부동 소수점 연산을 비롯하여 8비트, 16비트 및 32비트 정수 연산과 일부 64비트 연산을 지원합니다.

참고

부동 소수점 코드 벡터화가 항상 자동으로 수행되는 것은 아닙니다. 예를 들어 재연관이 필요한 루프는 --fpmode fast로 컴파일하는 경우에만 벡터화됩니다. --fpmode fast를 사용하여 컴파일하면 컴파일러에서 결과에 영향을 줄 수 있는 일부 변환을 수행할 수 있습니다. 컴파일러 참조 설명서의 2-63페이지의 --fpmode=model을 참조하십시오.

NEON 장치는 하나의 명령을 사용하여 벡터 레지스터에서 여러 요소에 대해 작동하는 벡터 SIMD 장치로 분류됩니다.

예를 들어 배열 A는 8개의 요소를 포함한 16비트 정수 배열입니다.

배열 B에는 이러한 8개의 요소가 있습니다.

두 배열을 더하려면 각 벡터를 벡터 레지스터로 가져오고 하나의 벡터 SIMD 명령어를 사용하여 결과를 가져옵니다.

표 3-1 배열 A

1 2 3 4 5 6 7 8

표 3-2 배열 B

80 70 60 50 40 30 20 10

표 3-3 결과

81 72 63 54 45 36 27 18

3-2 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 55: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

3.2 NEON용 코드 작성

이 단원에서는 NEON 장치에 대한 코드를 작성하는 방법에 대해 간략히 설명합니다. 다음과 같은 몇 가지 방법으로 NEON에서 실행하는 코드를 가져올 수 있습니다.

• 어셈블리 언어로 작성하거나 C에서 임베디드 어셈블리 언어를 사용하고 NEON 명령어를 직접 사용합니다.

• NEON C 언어 확장을 사용하여 C 또는 C++로 작성합니다.

• NEON 명령어를 사용하도록 최적화된 라이브러리 루틴을 호출합니다.

• 자동 벡터화를 사용하여 NEON에 대해 벡터화된 루프를 가져옵니다.

3.2.1 NEON C 확장

NEON C 확장은 C에서 NEON 장치에 액세스할 수 있도록 ARM에 의해 정의된 새 데이터 유형 및 intrinsic 함수의 세트입니다. 대부분의 벡터 함수는 NEON 장치에서 사용 가능한 벡터 명령어에 직접 매핑되며 NEON의 향상된 ARM C 컴파일러에서 인라인으로 컴파일됩니다. 이러한 확장을 사용하면 C 수준에서 성능을 향상시킬 수 있습니다. 이러한 성능 향상은 어셈블리 언어 코딩을 통해 얻을 수 있는 성능 향상과 유사합니다.

컴파일러 참조 설명서의 부록 E NEON 지원 사용을 참조하십시오.

3.2.2 자동 벡터화

명시적 NEON 명령어로 작성하는 대신 벡터화할 수 있는 루프로 코딩하면 프로세서 사이에 코드 이식성을 유지할 수 있습니다. 손으로 직접 코딩한 벡터화의 성능 수준과 비슷한 성능 수준을 적은 노력으로 달성할 수 있습니다.

예제 3-1에서는 Cortex-A8 프로세서에서 자동 벡터화를 호출하는 데 사용하는 명령 행 옵션의 예제를 보여 줍니다.

예제 3-1 자동 벡터화

armcc --vectorize --cpu=Cortex-A8 -O3 -Otime -c file.c

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 3-3ID090708 Non-Confidential, Unrestricted Access

Page 56: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

참고

-O2 -Otime을 사용하여 컴파일할 수도 있지만 최대 코드 성능을 제공하지는 않습니다.

3.2.3 성능 목표

대부분의 응용 프로그램은 벡터화를 통해 최상의 성능을 얻을 수 있도록 조정해야 합니다. 항상 약간의 오버헤드가 있으므로 이론적인 최대 성능에는 도달할 수 없습니다 예를 들어 NEON 장치는 한 번에 4개의 단일정밀도 부동 소수점을 처리할 수 있습니다. 이는 벡터화되지 않은 원래 스칼라 코드에서는 부동 소수점 응용 프로그램에 대한 이론적인 최대 성능 요소가 4임을 의미합니다. 일반적인 오버헤드를 고려할 때 전체 부동 소수점 응용 프로그램의 알맞은 목표는 스칼라 코드를 통해 성능의 50%를 향상시키는 것입니다. 완전히 벡터화되지 않은 대규모 응용 프로그램의 경우 적합한 목표는 스칼라 코드를 통해 성능의 25%를 향상시키는 것이지만, 이는 응용 프로그램마다 크게 다릅니다.

자세한 내용은 3-7페이지의 성능 향상을 참조하십시오.

3-4 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 57: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

3.3 자동 벡터화 사용

이 단원에서는 자동 벡터화에 대해 간략히 설명하고 생성된 코드의 벡터화 프로세스 및 성능에 영향을 미치는 요소에 대해 설명합니다.

3.3.1 자동 벡터화 개요

자동 벡터화는 코드에 있는 루프의 고수준 분석과 관련이 있습니다. 이는 대부분의 일반 코드를 NEON 장치의 기능에 매핑할 때 가장 효과적인 방법입니다. 대부분의 코드에서는 더 작은 스케일의 알고리즘 종속적 병렬화를 통해 얻을 수 있는 이득이 이러한 기회를 자동 분석하는 비용과 비교해볼 때 매우 적습니다. 이러한 이유로 인해 NEON 장치는 루프 기반 병렬화의 타겟으로 설계되었습니다.

벡터화는 최적화된 코드가 벡터화되지 않은 코드와 동일한 결과를 제공하는 방식으로 수행됩니다. 경우에 따라 루프의 벡터화가 수행되지 않아 잘못된 결과가 발생하지 않을 수 있습니다. 이는 하위 최적 코드가 될 수 있으므로 자동 벡터화에 보다 적합하도록 코드를 수동으로 조정해야 할 수도 있습니다. 자세한 내용은 3-7페이지의 성능 향상을 참조하십시오.

3.3.2 벡터화 개념

이 단원에서는 코드의 벡터화를 고려할 때 일반적으로 사용되는 몇 가지 개념에 대해 설명합니다.

데이터 참조

코드에 있는 데이터 참조는 다음 세 가지 유형 중 하나로 분류할 수 있습니다.

스칼라 루프의 모든 이터레이션에서 변경되지 않는 단일 위치입니다.

인덱스 루프의 각 패스마다 일정 양만큼 증가하는 정수의 양입니다.

벡터 연속적인 요소 간에 상수 스트라이드를 포함한 메모리 위치의 범위입니다.

3-6페이지의 예제 3-2에서는 루프에 있는 변수의 분류를 보여 줍니다.

i,j 인덱스 변수

a,b 벡터

x 스칼라

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 3-5ID090708 Non-Confidential, Unrestricted Access

Page 58: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

예제 3-2 벡터화할 수 있는 루프의 범주화

float *a, *b;int i, j, n;...for (i = 0; i < n; i++){

*(a+j) = x +b[i];j += 2;

};

벡터화를 수행하려면 컴파일러는 벡터 액세스 패턴으로 변수를 식별해야 하며 루프의 서로 다른 이터레이션 간에 데이터 종속성이 없는지 확인해야 합니다.

스트라이드 패턴 및 데이터 액세스

루프의 데이터 액세스 스트라이드 패턴은 순차적인 루프 이터레이션 간의 데이터 요소에 대한 액세스 패턴입니다. 예를 들어 배열의 각 요소에 연속적으로 액세스하는 루프에 있는 스트라이드가 1입니다. 또 다른 예로, 사용된 각 요소 간에 상수 오프셋을 포함한 배열에 액세스하는 루프가 상수 스트라이드를 포함하는 것으로 간주됩니다. 예제 3-2, b는 스트라이드 1로 액세스하고, a는 스트라이드 2로 액세스합니다.

3.3.3 벡터화 성능에 영향을 미치는 요소

생성된 코드의 자동 벡터화 프로세스 및 성능에 영향을 미치는 사항은 다음과 같습니다.

루프가 구성된 방식

성능을 극대화하려면 루프 중첩에 있는 맨 안쪽의 루프가 스트라이드가 1인 배열에 액세스해야 합니다.

데이터가 구성된 방식

NEON 레지스터에 보유할 수 있는 데이터 요소의 수 및 병렬적으로 수행할 수 있는 연산 수를 데이터 형식에서 결정할 수 있습니다.

3-6 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 59: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

루프의 이터레이션 수

루프 오버헤드는 이터레이션이 많을수록 감소하기 때문에 일반적으로 이터레이션 수가 많은 것이 좋습니다. 두 개 또는 세 개의 요소 같이 이터레이션 수가 매우 적은 경우에는 비벡터 명령어를 사용하여 처리하는 작업을 보다 신속하게 수행할 수 있습니다.

배열의 데이터 유형

예를 들어 배정밀도 부동 소수점 배열이 사용되는 경우 NEON에서 성능을 향상시킬 수 없습니다.

메모리 계층 사용

대부분의 최신 프로세서의 경우 메모리 대역폭과 프로세서 용량 간의 균형이 비교적 맞지 않습니다. 예를 들어 주 메모리에서 검색된 큰 데이터 세트에서 상대적으로 매우 적은 수의 산술 연산을 수행하는 작업은 시스템의 메모리 대역폭에 의해 제한을 받습니다.

3.3.4 성능 향상

대부분의 응용 프로그램에서는 최상의 NEON 결과를 얻기 위해 프로그래머가 어느 정도 조정 작업을 수행해야 합니다. 이 단원에서는 여러 가지 루프 유형에 대해 설명합니다. 그리고 벡터화가 일부 루프에서는 성공적으로 작동하지만 다른 루프에서는 제대로 작동하지 않는 방식에 대해 설명합니다. 벡터화된 코드를 통해 최상의 성능을 얻을 수 있도록 코드를 수정하는 방법에 대해서도 설명합니다.

일반적인 성능 문제

명령 행 옵션 -O3 및 -Otime을 사용하면 코드를 통해 벡터화의 성능 향상을 비롯하여 상당한 성능 향상 효과를 얻을 수 있습니다.

성능을 위해 최적화하는 경우 고수준 알고리즘 구조, 데이터 요소 크기, 배열 구성, 엄격한 반복 루프, 축소 연산 및 데이터 종속성 문제를 고려해야 합니다. 성능을 위해 최적화하려면 프로그램을 이해하는 데 대부분의 시간을 할애해야 합니다. 성능을 극대화하기 위해 실제 상황에서 코드의 프로파일링 및 벤치마킹을 사용해야 할 수도 있습니다.

자동 벡터화 기능은 코드에 대한 이전의 수동 최적화, 예를 들어 소스 코드 또는 복잡한 배열 액세스에서의 수동 루프 언롤링으로 인해 저하될 수도 있습니다. 최상의 결과를 얻기 위한 가장 좋은 방법은 컴파일러가 최적화를 모두 수행할 수 있

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 3-7ID090708 Non-Confidential, Unrestricted Access

Page 60: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

도록 단순 루프를 사용하여 코드를 작성하는 것입니다. 수동으로 최적화된 레거시 코드의 경우에는 단순 루프를 사용하여 원래 알고리즘을 기반으로 중요한 부분을 다시 작성하는 것이 더 간단할 수 있습니다.

자세한 내용은 컴파일러 참조 설명서에서 다음을 참조하십시오.

• 컴파일러 참조 설명서의 2-140페이지의 --vectorize, --no_vectorize

• 컴파일러 참조 설명서의 2-102페이지의 -Onum

• 컴파일러 참조 설명서의 2-105페이지의 -Otime

데이터 종속성

하나의 이터레이션에서 얻은 결과가 동일한 루프의 추후 이터레이션으로 피드백되는 루프에 데이터 종속성 충돌이 있다고 합니다. 충돌하는 값은 누산 합계와 같은 배열 요소 또는 스칼라일 수 있습니다.

데이터 종속성 충돌을 포함하는 루프는 완전히 최적화되지 않을 수도 있습니다. 배열 및/또는 포인터와 관련된 데이터 종속성을 검색하려면 각 루프 중첩에 사용된 배열을 광범위하게 분석하고, 루프에 사용되고 저장된 각 배열 차원을 따라 요소에 대한 액세스의 오프셋 및 스트라이드를 검사해야 합니다. 루프의 다른 이터레이션에서 중복되는 배열을 사용하고 저장해야 할 경우에는 데이터 종속성 문제가 발생할 수 있습니다. 연산의 벡터 순서가 결과를 변경할 수 있는 경우에는 루프를 안전하게 벡터화할 수 없습니다. 이 경우 컴파일러는 문제를 감지하고 원래 형식의 루프를 그대로 두거나 루프의 벡터화를 부분적으로 수행합니다. 성능을 극대화하려면 코드에서 이러한 유형의 데이터 종속성이 존재하지 않도록 해야 합니다.

예제 3-3의 루프에서는 루프의 맨 위에 있는 a[i-2]에 대한 참조가 맨 아래에 있는 a[i]로의 저장과 충돌합니다. 이 루프에서 벡터화를 수행하면 다른 결과가 발생하며 루프가 원래 형식으로 남아 있게 됩니다.

예제 3-3 벡터화할 수 없는 데이터 종속성

float a[99], b[99], t;int i;for (i = 3; i < 99; i++){

t = a[i-1] + a[i-2];

3-8 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 61: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

b[i] = t + 3.0 + a[i];a[i] = sqrt(b[i]) - 5.0;

};

다른 배열 첨자에서 가져온 정보는 종속성을 분석하는 데 사용됩니다. 예제 3-4의 경우 배열 a에 대한 참조의 비벡터 첨자는 같을 수 없으며 n이 n+1과 같지 않으므로 루프가 벡터화되어 이터레이션 간에 피드백이 수행되지 않습니다. 배열 a에 대한 참조는 배열에 있는 두 개의 서로 다른 부분을 사용하므로 데이터를 공유하지 않습니다.

예제 3-4 벡터화할 수 있는 데이터 종속성

float a[99][99], b[99], c[99];int i, n, m;...for (i = 1; i < m; i++) a[n][i] = a[n+1][i-1] * b[i] + c[i];

스칼라 변수

NEON 루프에서 사용되지만 설정되지 않은 스칼라 변수는 벡터 레지스터에 있는 각 위치에 복제되며 결과는 벡터 계산에 사용됩니다.

루프에 설정되고 사용되는 스칼라는 벡터로 승격됩니다. 일반적으로 이러한 변수에는 임시 벡터 값을 보유해야 하는 루프의 임시 스칼라 값이 포함되어 있습니다. 예제 3-5에서 x는 사용된 스칼라이고 y는 승격된 스칼라입니다.

예제 3-5 벡터화할 수 있는 루프

float a[99], b[99], x, y;int i, n;...for (i = 0; i < n; i++){

y = x + b[i];a[i] = y + 1/y;

};

루프에서 사용되고 설정된 스칼라를 캐리 순환 스칼라라고 합니다. 이러한 변수는 루프의 한 패스에서 계산된 값이 다음 패스로 전달되기 때문에 벡터화를 방해할 수 있습니다. 3-10페이지의 예제 3-6에서 x는 캐리 순환 스칼라입니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 3-9ID090708 Non-Confidential, Unrestricted Access

Page 62: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

예제 3-6 벡터화할 수 없는 루프

float a[99], b[99], x;int i, n;...for (i = 0; i < n; i++){

a[i] = x + b[i];x = a[i] + 1/x;

};

축소 연산

루프에서 사용되는 스칼라의 특별한 범주가 축소 연산입니다. 이 범주는 값 벡터를 축소하여 스칼라 결과를 도출하는 작업과 관련이 있습니다. 가장 일반적인 축소는 벡터의 모든 요소를 합하는 것입니다. 그 외 축소에는 두 벡터의 내적, 벡터의 최대값, 벡터의 최소값, 모든 벡터 요소의 곱, 벡터의 최대 또는 최소 요소 위치가 포함됩니다.

예제 3-7에서는 내적 축소를 보여 줍니다. 여기서 x는 축소 스칼라입니다.

예제 3-7 내적 축소

float a[99], b[99], x;int i, n;...for (i = 0; i < n; i++) x += a[i] * b[i];

축소 연산은 자주 수행되므로 벡터화하는 것이 좋습니다. 일반적으로 축소 연산은 이후에 최종 결과 스칼라로 축소되는 부분 축소 벡터를 만들어 벡터화됩니다.

포인터 사용

배열에 액세스할 때 컴파일러는 보통 메모리 액세스가 겹치지 않는지를 확인할 수 있습니다. 그러나 포인터를 사용할 때는 대부분 이를 확인하지 않으며, 이를 확인하려면 런타임 테스트를 수행하거나 restrict를 사용해야 합니다.

3-10 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 63: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

컴파일러는 루프가 안전한지 확인할 수 있는 경우 포인터가 포함된 루프를 벡터화할 수 있습니다. 메모리에 대한 벡터 액세스가 있는지 확인하기 위해 루프의 배열 참조와 포인터 참조를 모두 분석합니다. 경우에 따라 컴파일러는 런타임 테스트를 만들고 테스트 결과에 따라 벡터 버전 또는 스칼라 버전의 루프를 실행합니다.

함수 인수는 대개 포인터로 전달됩니다. 여러 포인터 변수가 함수에 전달되면 메모리의 중복되는 섹션을 가리킬 수 있습니다. 런타임에 예외적인 경우도 있지만 일반적으로 컴파일러는 항상 안전한 방법을 따르고 할당 연산자의 왼쪽과 오른쪽 모두에 나타나는 포인터와 관련된 루프의 최적화는 수행하지 않습니다. 예를 들어 예제 3-8에서의 함수를 살펴 보십시오.

예제 3-8 조건부 포인터 벡터화

void func (int *pa, int *pb, int x){

int i;for (i = 0; i < 100; i++) *(pa + i) = *(pb + i) + x;

};

이 예제에서 pa 및 pb가 한 루프 패스의 결과가 다음 루프 패스로 피드백되도록 하는 방식으로 메모리에서 겹치는 경우 루프를 벡터화하면 잘못된 결과가 나타날 수 있습니다. 함수가 다음 인수를 사용하여 호출되면 벡터화가 모호해질 수 있습니다.

int *a;

func (a, a-1);

컴파일러는 포인터 별칭이 발생하는지 확인하기 위해 런타임 테스트를 수행합니다. 포인터 별칭이 발생하지 않으면 코드의 벡터화 버전이 실행됩니다. 포인터 별칭이 발생하면 원래의 벡터화되지 않은 코드가 대신 실행됩니다. 이렇게 하면 런타임 효율성 및 코드 크기에 있어서 비용을 줄일 수 있습니다.

실제로는 함수 인수 때문에 데이터 종속성이 거의 존재하지 않습니다. 중복되는 포인터를 전달하는 프로그램을 벡터화 관련 문제와 별도로 이해하고 디버깅하는 것은 매우 어렵습니다.

컴파일러 참조 설명서의 3-9페이지의 restrict를 참조하십시오. 예제 3-8에서는 restrict를 pa에 추가하면 런타임 테스트를 수행하지 않아도 됩니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 3-11ID090708 Non-Confidential, Unrestricted Access

Page 64: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

간접 주소 지정

간접 주소 지정은 값 벡터에서 배열에 액세스한 경우 발생합니다. 배열을 메모리에서 가져오는 경우 이 작업을 수집이라고 합니다. 배열이 메모리에 저장되는 경우 이 작업을 스캐터라고 합니다. 예제 3-9에서 a는 스캐터되고 b는 수집됩니다.

예제 3-9 벡터화할 수 없는 간접 주소 지정

float a[99], b[99];int ia[99], ib[99], i, n, j;...for (i = 0; i < n; i++) a[ia[i]] = b[j + ib[i]];

간접 주소 지정은 메모리에 연속적으로 저장된 벡터만 다룰 수 있으므로 NEON 장치를 통해 벡터화할 수 없습니다. 루프에 간접 주소 지정 및 중요한 계산이 있는 경우 간접 주소 지정을 벡터가 아닌 별도의 루프로 이동하는 것이 보다 효율적일 수 있습니다. 이렇게 하면 계산을 효과적으로 벡터화할 수 있습니다.

루프 구조

루프의 전체 구조는 벡터화를 통해 최상의 성능을 얻는 데 중요합니다. 일반적으로 루프의 시작 부분에 고정되어 있고 복잡한 조건문이나 조건부 종료를 포함하지 않는 이터레이션 수를 사용하여 단순한 루프를 작성하는 것이 가장 좋습니다. 코드의 벡터화 성능을 향상시키기 위해 루프를 다시 작성해야 할 수도 있습니다.

루프에서 종료

또한 예제 3-10은 루프에서 종료를 포함하므로 벡터화할 수 없습니다. 이 경우 벡터화에 성공하려면 가능한 경우 루프를 다시 작성해야 합니다.

예제 3-10 벡터화할 수 없는 루프

int a[99], b[99], c[99], i, n;...for (i = 0; i < n; i++){

a[i] = b[i] + c[i];if (a[i] > 5) break;

};

3-12 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 65: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

루프 이터레이션 수

루프의 시작 부분에는 고정된 이터레이션 수가 있어야 합니다. 예제 3-11에서는 이터레이션 수가 n이며 이 수가 루프를 진행하는 동안 변경되지 않음을 보여 줍니다.

예제 3-11 벡터화할 수 있는 루프

int a[99], b[99], c[99],i, n;...for (i = 0; i < n; i++) a[i] = b[i] + c[i];

예제 3-12는 고정된 이터레이션 수를 포함하지 않으며 자동으로 벡터화할 수 없습니다.

예제 3-12 벡터화할 수 없는 루프

int a[99], b[99], c[99], i, n;...while (i < n){

a[i] = b[i] + c[i];i += a[i];

};

NEON 장치는 2, 4, 8 또는 16 그룹의 요소에서 작동할 수 있습니다. 루프의 시작 부분에 있는 이터레이션 수가 알려진 경우 컴파일러는 런타임 테스트를 추가하여 이터레이션 수가 NEON 레지스터의 적합한 데이터 유형에 사용될 수 있는 레인의 배수가 아닌지 확인합니다. 이렇게 하면 추가로 벡터화되지 않은 코드가 생성되어 모든 추가 루프 이터레이션을 샐행하기 때문에 코드 크기가 늘어납니다.

이터레이션 수가 NEON에서 지원하는 이터레이션 수 중 하나임을 알고 있는 경우에는 이를 컴파일러에 알릴 수 있습니다. 가장 효과적인 방법은 호출자에서 이터레이션 수를 4로 나눠 벡터화하려는 함수에서 4를 곱하는 것입니다. 모든 호출 함수를 수정할 수는 없는 경우 루프 제한 테스트에 적절한 식을 사용하여 루프 이터레이션이 적합한 배수임을 나타낼 수 있습니다. 예를 들어 루프 이터레이션이 4의 배수임을 나타내려면 다음을 사용합니다.

for(i = 0; i < (n >> 2 << 2); i++)

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 3-13ID090708 Non-Confidential, Unrestricted Access

Page 66: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

또는

for(i = 0; i < (n & ~3); i++)

이렇게 하면 생성된 코드의 크기를 줄이고 성능을 향상시킬 수 있습니다.

구조체의 모든 부분을 함께 사용하도록 루프를 작성하는 것은 벡터화에 중요합니다. 동일한 루프 내에서 각 구조체 부분에 액세스해야 합니다.

예제 3-13 벡터화할 수 없는 루프

for (...) { buffer[i].a = ....; }for (...) { buffer[i].b = ....; }for (...) { buffer[i].c = ....; }

예제 3-14 벡터화할 수 있는 루프

for (...){

buffer[i].a = ....;buffer[i].b = ....;buffer[i].c = ....;

}

함수 호출 및 인라인

루프 내에서 인라인이 아닌 함수를 호출하면 벡터화를 수행할 수 없습니다.

일반적으로는 이해하기 쉽도록 복잡한 연산을 여러 함수로 나눕니다. 이러한 함수에 대해 벡터화를 고려하려면 해당 함수를 __inline 또는 __forceinline 키워드를 사용하여 표시해야 합니다. 그러면 이러한 함수가 벡터화를 위해 인라인으로 확장됩니다. 컴파일러 참조 설명서의 4-10페이지의 __inline 및 4-7페이지의 __forceinline을 참조하십시오.

조건문

효과적인 벡터화를 위해 루프에는 대개 할당문이 포함되어야 하고 if 및 switch 문은 되도록이면 제한적으로 사용해야 합니다.

3-14 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 67: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

루프의 이터레이션 간에 변경되지 않는 단순한 조건을 불변 루프라고 합니다. 이는 컴파일러에 의해 루프 앞으로 이동할 수 있으므로 각 루프 이터레이션에서 실행할 필요가 없습니다. 더 복잡한 조건부 연산은 벡터 모드에 있는 모든 경로를 계산하고 결과를 병합하여 벡터화됩니다. 조건부로 수행해야 할 중요한 계산이 있는 경우에는 상당히 많은 시간이 소요됩니다.

예제 3-15에서는 사용할 수 있는 조건문을 보여 줍니다.

예제 3-15 벡터화할 수 있는 조건

float a[99], b[99], c[i];int i, n;...for (i = 0; i < n; i++){

if (c[i] > 0) a[i] = b[i] - 5.0;else a[i] = b[i] * 2.0;

};

구조체

NEON 구조체 로드 시에는 단일 구조체의 모든 구성원 길이가 같아야 합니다. 따라서 컴파일러는 예제 3-16에 나와 있는 코드에 대해 벡터 로드를 사용하지 않습니다.

예제 3-16 데이터 형식 불일치로 인해 벡터화할 수 없는 코드

struct foo{

short a;int b;short c;

} n[10];

구조체 전체에서 동일한 데이터 형식을 사용하여 예제 3-16의 코드를 벡터화용으로 다시 작성할 수 있습니다. 예를 들어 b를 정수 데이터 형식으로 지정하려면 a 및 c를 정수 데이터 형식으로 교체할 수 있습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 3-15ID090708 Non-Confidential, Unrestricted Access

Page 68: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

구조체에 패딩을 적용하면 벡터화를 수행할 수 없습니다. 예제 3-17에서는 모든 a 구성요소를 정렬해도 아무런 이점이 없습니다. NEON 장치는 정렬되지 않은 구조체도 성능 저하 없이 로드할 수 있기 때문입니다.

예제 3-17 정렬 패딩으로 인해 벡터화할 수 없는 코드

struct aligned_data{

char a;char b;char c;char not_used;

} n[10];

not_used 패딩을 제거하면 예제 3-17의 코드를 벡터화용으로 다시 작성할 수 있습니다.

소스 코드 조정을 통한 성능 향상의 예제

컴파일러는 벡터화 최적화가 성공적으로 적용된 경우와 벡터화 적용에 실패한 경우를 나타내는 진단 정보를 제공할 수 있습니다. 컴파일러 참조 설명서의 2-50페이지의 --diag_suppress=optimizations 및 2-51페이지의 --diag_warning=optimizations를 참조하십시오.

예제 3-18에서는 배열에 단순한 합계 연산을 구현하는 두 개의 함수를 보여 줍니다. 이 코드는 벡터화되지 않습니다.

예제 3-18 벡터화할 수 없는 코드

int addition(int a, int b){

return a + b;}void add_int(int *pa, int *pb, unsigned int n, int x){

unsigned int i;for(i = 0; i < n; i++) *(pa + i) = addition(*(pb + i),x);

}

--diag_warnings=optimization 옵션을 사용하면 addition() 함수에 대한 최적화 경고 메시지가 생성됩니다.

3-16 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 69: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

__inline 한정자를 addition() 정의에 추가하면 이 코드가 벡터화되지만 아직 최적의 상태는 아닙니다. --diag_warnings=optimization 옵션을 다시 사용하면 루프가 벡터화되지만 포인터 별칭 문제가 발생할 수 있다는 최적화 경고 메시지가 생성됩니다.

컴파일러는 별칭에 대한 런타임 테스트를 생성해야 하며 코드의 벡터화된 복사본 및 스칼라 복사본을 모두 출력해야 합니다. 예제 3-19에서는 포인터의 별칭이 지정되지 않은 경우 restrict 키워드를 사용하여 성능을 향상시킬 수 있는 방법을 보여 줍니다.

예제 3-19 restrict를 사용하여 벡터화 성능 향상

__inline int addition(int a, int b){

return a + b;}void add_int(int * __restrict pa, int * __restrict pb, unsigned int n, int x){

unsigned int i;for(i = 0; i < n; i++) *(pa + i) = addition(*(pb + i),x);

}

마지막으로 시도해 볼 수 있는 성능 향상 노력은 루프 이터레이션의 수와 관련이 있습니다. 예제 3-19에서 이터레이션 수는 고정되어 있지 않으며 NEON 레지스터에 정확하게 맞는 배수가 아닐 수 있습니다. 이는 컴파일러에서 벡터화되지 않은 코드를 사용하여 실행할 남아 있는 이터레이션을 테스트해야 함을 의미합니다. 이터레이션 수가 NEON에서 지원하는 이터레이션 수 중 하나임을 알고 있는 경우 이를 컴파일러에 알릴 수 있습니다. 예제 3-20에서는 벡터화를 통해 최상의 성능을 얻기 위해 마지막으로 기울일 수 있는 노력을 보여 줍니다.

예제 3-20 최상의 벡터화 성능을 위해 조정된 코드

__inline int addition(int a, int b){

return a + b;}void add_int(int * __restrict pa, int * __restrict pb, unsigned int n, int x){

unsigned int i;

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 3-17ID090708 Non-Confidential, Unrestricted Access

Page 70: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

for(i = 0; i < (n & ~3); i++) *(pa + i) = addition(*(pb + i),x); /* n is a multiple of 4 */

}

__promise를 사용하여 벡터화 향상

__promise(expr) 내장 함수는 컴파일러에 지정된 식이 0이 아니라는 것을 확인해 줍니다. 이를 바탕으로 컴파일러는 중복된 코드 제외 작업을 최적화하여 벡터화를 향상시킬 수 있습니다.

예제 3-21의 디스어셈블된 결과를 통해 __promise를 적용함에 따라 스칼라 개량 루프가 제거되어 벡터화된 단순 루프로 디스어셈블리 작업이 줄어드는 것을 알 수 있습니다.

예제 3-21 __promise(expr)를 사용하여 벡터화 코드 향상

void f(int *x, int n){

int i;__promise((n > 0) && ((n&7)==0));for (i=0; i<n;i++) x[i]++;

}

3-17페이지의 예제 3-20은 __promise()의 사용에 따른 이점을 보여주는 유사한 예입니다.

3-18 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 71: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

3.4 예

다음은 벡터화 코드의 예제입니다. 예제 3-22 및 3-21페이지의 예제 3-23를 참조하십시오.

예제 3-22 벡터화 코드

/** Vectorizable example code.* Copyright 2006 ARM Limited. All rights reserved.** Includes embedded assembly to initialize cpu; link using '--entry=init_cpu'.** Build using:* armcc --vectorize -c vector_example.c --cpu Cortex-A8 -Otime* armlink -o vector_example.axf vector_example.o --entry=init_cpu*/

#include <stdio.h>void fir(short *__restrict y, const short *x, const short *h, int n_out, int n_coefs){

int n;for (n = 0; n < n_out; n++){

int k, sum = 0;for (k = 0; k < n_coefs; k++){

sum += h[k] * x[n - n_coefs + 1 + k];}y[n] = ((sum>>15) + 1) >> 1;

}}int main(){

static const short x[128] ={

0x0000, 0x0647, 0x0c8b, 0x12c8, 0x18f8, 0x1f19, 0x2528, 0x2b1f,0x30fb, 0x36ba, 0x3c56, 0x41ce, 0x471c, 0x4c3f, 0x5133, 0x55f5,0x5a82, 0x5ed7, 0x62f2, 0x66cf, 0x6a6d, 0x6dca, 0x70e2, 0x73b5,0x7641, 0x7884, 0x7a7d, 0x7c29, 0x7d8a, 0x7e9d, 0x7f62, 0x7fd8,0x8000, 0x7fd8, 0x7f62, 0x7e9d, 0x7d8a, 0x7c29, 0x7a7d, 0x7884,0x7641, 0x73b5, 0x70e2, 0x6dca, 0x6a6d, 0x66cf, 0x62f2, 0x5ed7,0x5a82, 0x55f5, 0x5133, 0x4c3f, 0x471c, 0x41ce, 0x3c56, 0x36ba,0x30fb, 0x2b1f, 0x2528, 0x1f19, 0x18f8, 0x12c8, 0x0c8b, 0x0647,0x0000, 0xf9b9, 0xf375, 0xed38, 0xe708, 0xe0e7, 0xdad8, 0xd4e1,0xcf05, 0xc946, 0xc3aa, 0xbe32, 0xb8e4, 0xb3c1, 0xaecd, 0xaa0b,0xa57e, 0xa129, 0x9d0e, 0x9931, 0x9593, 0x9236, 0x8f1e, 0x8c4b,0x89bf, 0x877c, 0x8583, 0x83d7, 0x8276, 0x8163, 0x809e, 0x8028,

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 3-19ID090708 Non-Confidential, Unrestricted Access

Page 72: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

0x8000, 0x8028, 0x809e, 0x8163, 0x8276, 0x83d7, 0x8583, 0x877c,0x89bf, 0x8c4b, 0x8f1e, 0x9236, 0x9593, 0x9931, 0x9d0e, 0xa129,0xa57e, 0xaa0b, 0xaecd, 0xb3c1, 0xb8e4, 0xbe32, 0xc3aa, 0xc946,0xcf05, 0xd4e1, 0xdad8, 0xe0e7, 0xe708, 0xed38, 0xf375, 0xf9b9,

};static const short coeffs[8] ={

0x0800, 0x1000, 0x2000, 0x4000,0x4000, 0x2000, 0x1000, 0x0800

};int i, ok = 1;short y[128];static const short expected[128] ={

0x1474, 0x1a37, 0x1fe9, 0x2588, 0x2b10, 0x307d, 0x35cc, 0x3afa,0x4003, 0x44e5, 0x499d, 0x4e27, 0x5281, 0x56a9, 0x5a9a, 0x5e54,0x61d4, 0x6517, 0x681c, 0x6ae1, 0x6d63, 0x6fa3, 0x719d, 0x7352,0x74bf, 0x6de5, 0x66c1, 0x5755, 0x379e, 0x379e, 0x5755, 0x66c1,0x6de5, 0x74bf, 0x7352, 0x719d, 0x6fa3, 0x6d63, 0x6ae1, 0x681c,0x6517, 0x61d4, 0x5e54, 0x5a9a, 0x56a9, 0x5281, 0x4e27, 0x499d,0x44e5, 0x4003, 0x3afa, 0x35cc, 0x307d, 0x2b10, 0x2588, 0x1fe9,0x1a37, 0x1474, 0x0ea5, 0x08cd, 0x02f0, 0xfd10, 0xf733, 0xf15b,0xeb8c, 0xe5c9, 0xe017, 0xda78, 0xd4f0, 0xcf83, 0xca34, 0xc506,0xbffd, 0xbb1b, 0xb663, 0xb1d9, 0xad7f, 0xa957, 0xa566, 0xa1ac,0x9e2c, 0x9ae9, 0x97e4, 0x951f, 0x929d, 0x905d, 0x8e63, 0x8cae,0x8b41, 0x8a1b, 0x893f, 0x88ab, 0x8862, 0x8862, 0x88ab, 0x893f,0x8a1b, 0x8b41, 0x8cae, 0x8e63, 0x905d, 0x929d, 0x951f, 0x97e4,0x9ae9, 0x9e2c, 0xa1ac, 0xa566, 0xa957, 0xad7f, 0xb1d9, 0xb663,0xbb1b, 0xbffd, 0xc506, 0xca34, 0xcf83, 0xd4f0, 0xda78, 0xe017,0xe5c9, 0xebcc, 0xf229, 0xf96a, 0x02e9, 0x0dd8, 0x1937, 0x24ce,

};fir(y, x + 7, coeffs, 128, 8);for (i = 0; i < sizeof(y)/sizeof(*y); ++i){

if (y[i] != expected[i]){

printf("mismatch: y[%d] = 0x%04x; expected[%d] = 0x%04x\n", i, y[i], i, expected[i]);ok = 0;break;

}}if (ok) printf("** TEST PASSED OK **\n");return ok ? 0 : 1;

}#ifdef __TARGET_ARCH_7_A__asm void init_cpu() {

// Set up CPU stateMRC p15,0,r4,c1,c0,0ORR r4,r4,#0x00400000 // enable unaligned mode (U=1)

3-20 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 73: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

BIC r4,r4,#0x00000002 // disable alignment faults (A=0)// MMU not enabled: no page tables

MCR p15,0,r4,c1,c0,0#ifdef __BIG_ENDIAN

SETEND BE#endif

MRC p15,0,r4,c1,c0,2 // Enable VFP access in the CAR -ORR r4,r4,#0x00f00000 // must be done before any VFP instructionsMCR p15,0,r4,c1,c0,2MOV r4,#0x40000000 // Set EN bit in FPEXCMSR FPEXC,r4IMPORT __mainB __main

}#endif

예제 3-23 DSP 벡터화 코드

/** DSP Vectorizable example code.* Copyright 2006 ARM Limited. All rights reserved.** Includes embedded assembly to initialize cpu; link using '--entry=init_cpu'.** Build using:* armcc -c dsp_vector_example.c --cpu Cortex-A8 -Otime --vectorize* armlink -o dsp_vector_example.axf dsp_vector_example.o --entry=init_cpu*/#include <stdio.h>#include "dspfns.h"void fn(short *__restrict r, int n, const short *__restrict a, const short *__restrict b){

int i;for (i = 0; i < n; ++i){

r[i] = add(a[i], b[i]);}

}int main(){

static const short x[128] ={

0x0000, 0x0647, 0x0c8b, 0x12c8, 0x18f8, 0x1f19, 0x2528, 0x2b1f,0x30fb, 0x36ba, 0x3c56, 0x41ce, 0x471c, 0x4c3f, 0x5133, 0x55f5,0x5a82, 0x5ed7, 0x62f2, 0x66cf, 0x6a6d, 0x6dca, 0x70e2, 0x73b5,0x7641, 0x7884, 0x7a7d, 0x7c29, 0x7d8a, 0x7e9d, 0x7f62, 0x7fd8,

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 3-21ID090708 Non-Confidential, Unrestricted Access

Page 74: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

0x8000, 0x7fd8, 0x7f62, 0x7e9d, 0x7d8a, 0x7c29, 0x7a7d, 0x7884,0x7641, 0x73b5, 0x70e2, 0x6dca, 0x6a6d, 0x66cf, 0x62f2, 0x5ed7,0x5a82, 0x55f5, 0x5133, 0x4c3f, 0x471c, 0x41ce, 0x3c56, 0x36ba,0x30fb, 0x2b1f, 0x2528, 0x1f19, 0x18f8, 0x12c8, 0x0c8b, 0x0647,0x0000, 0xf9b9, 0xf375, 0xed38, 0xe708, 0xe0e7, 0xdad8, 0xd4e1,0xcf05, 0xc946, 0xc3aa, 0xbe32, 0xb8e4, 0xb3c1, 0xaecd, 0xaa0b,0xa57e, 0xa129, 0x9d0e, 0x9931, 0x9593, 0x9236, 0x8f1e, 0x8c4b,0x89bf, 0x877c, 0x8583, 0x83d7, 0x8276, 0x8163, 0x809e, 0x8028,0x8000, 0x8028, 0x809e, 0x8163, 0x8276, 0x83d7, 0x8583, 0x877c,0x89bf, 0x8c4b, 0x8f1e, 0x9236, 0x9593, 0x9931, 0x9d0e, 0xa129,0xa57e, 0xaa0b, 0xaecd, 0xb3c1, 0xb8e4, 0xbe32, 0xc3aa, 0xc946,0xcf05, 0xd4e1, 0xdad8, 0xe0e7, 0xe708, 0xed38, 0xf375, 0xf9b9,

};static const short y[128] ={

0x8000, 0x7fd8, 0x7f62, 0x7e9d, 0x7d8a, 0x7c29, 0x7a7d, 0x7884,0x7641, 0x73b5, 0x70e2, 0x6dca, 0x6a6d, 0x66cf, 0x62f2, 0x5ed7,0x5a82, 0x55f5, 0x5133, 0x4c3f, 0x471c, 0x41ce, 0x3c56, 0x36ba,0x30fb, 0x2b1f, 0x2528, 0x1f19, 0x18f8, 0x12c8, 0x0c8b, 0x0647,0x0000, 0xf9b9, 0xf375, 0xed38, 0xe708, 0xe0e7, 0xdad8, 0xd4e1,0xcf05, 0xc946, 0xc3aa, 0xbe32, 0xb8e4, 0xb3c1, 0xaecd, 0xaa0b,0xa57e, 0xa129, 0x9d0e, 0x9931, 0x9593, 0x9236, 0x8f1e, 0x8c4b,0x89bf, 0x877c, 0x8583, 0x83d7, 0x8276, 0x8163, 0x809e, 0x8028,0x8000, 0x8028, 0x809e, 0x8163, 0x8276, 0x83d7, 0x8583, 0x877c,0x89bf, 0x8c4b, 0x8f1e, 0x9236, 0x9593, 0x9931, 0x9d0e, 0xa129,0xa57e, 0xaa0b, 0xaecd, 0xb3c1, 0xb8e4, 0xbe32, 0xc3aa, 0xc946,0xcf05, 0xd4e1, 0xdad8, 0xe0e7, 0xe708, 0xed38, 0xf375, 0xf9b9,0x0000, 0x0647, 0x0c8b, 0x12c8, 0x18f8, 0x1f19, 0x2528, 0x2b1f,0x30fb, 0x36ba, 0x3c56, 0x41ce, 0x471c, 0x4c3f, 0x5133, 0x55f5,0x5a82, 0x5ed7, 0x62f2, 0x66cf, 0x6a6d, 0x6dca, 0x70e2, 0x73b5,0x7641, 0x7884, 0x7a7d, 0x7c29, 0x7d8a, 0x7e9d, 0x7f62, 0x7fd8,

};short r[128];static const short expected[128] ={

0x8000, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,0x8000, 0x7991, 0x72d7, 0x6bd5, 0x6492, 0x5d10, 0x5555, 0x4d65,0x4546, 0x3cfb, 0x348c, 0x2bfc, 0x2351, 0x1a90, 0x11bf, 0x08e2,0x0000, 0xf71e, 0xee41, 0xe570, 0xdcaf, 0xd404, 0xcb74, 0xc305,0xbaba, 0xb29b, 0xaaab, 0xa2f0, 0x9b6e, 0x942b, 0x8d29, 0x866f,0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,0x8000, 0x866f, 0x8d29, 0x942b, 0x9b6e, 0xa2f0, 0xaaab, 0xb29b,0xbaba, 0xc305, 0xcb74, 0xd404, 0xdcaf, 0xe570, 0xee41, 0xf71e,0x0000, 0x08e2, 0x11bf, 0x1a90, 0x2351, 0x2bfc, 0x348c, 0x3cfb,

3-22 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 75: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

0x4546, 0x4d65, 0x5555, 0x5d10, 0x6492, 0x6bd5, 0x72d7, 0x7991,};int i, ok = 1;

fn(r, sizeof(r)/sizeof(*r), x, y);

for (i = 0; i < sizeof(r)/sizeof(*r); ++i){

if (r[i] != expected[i]){

printf("mismatch: r[%d] = 0x%04x; expected[%d] = 0x%04x\n", i, r[i], i, expected[i]);ok = 0;break;

}}if (ok) printf("** TEST PASSED OK **\n");

return ok ? 0 : 1;}#ifdef __TARGET_ARCH_7_A__asm void init_cpu(){

// Set up CPU stateMRC p15,0,r4,c1,c0,0ORR r4,r4,#0x00400000 // enable unaligned mode (U=1)BIC r4,r4,#0x00000002 // disable alignment faults (A=0)// MMU not enabled: no page tablesMCR p15,0,r4,c1,c0,0

#ifdef __BIG_ENDIANSETEND BE

#endifMRC p15,0,r4,c1,c0,2 // Enable VFP access in the CAR -ORR r4,r4,#0x00f00000 // must be done before any VFP instructionsMCR p15,0,r4,c1,c0,2MOV r4,#0x40000000 // Set EN bit in FPEXCMSR FPEXC,r4IMPORT __mainB __main

}#endif

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 3-23ID090708 Non-Confidential, Unrestricted Access

Page 76: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

NEON 벡터화 컴파일러 사용

3-24 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 77: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

4장 컴파일러 기능

이 장에서는 ARM 컴파일러 관련 기능에 대해 간략히 설명합니다. 이 장은 다음 단원으로 구성되어 있습니다.

• 4-2페이지의 내장 함수

• 4-14페이지의 Pragma

• 4-16페이지의 비트 밴딩

• 4-20페이지의 스레드-지역 스토리지

• 4-21페이지의 8바이트 정렬 기능

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 4-1ID090708 Non-Confidential, Unrestricted Access

Page 78: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

4.1 내장 함수

ARM 컴파일러는 다음과 같은 여러 가지 내장 함수 계열을 지원합니다.

• C 및 C++ 코드에서 ARM, Thumb 및 NEON 명령어를 인식하는 데 필요한 명령어 내장 함수

• ETSI 기본 연산을 인식하는 내장 함수

• TI C55x 컴파일러에 있는 내장 함수를 에뮬레이션하는 내장 함수

• NEON™ 벡터화 컴파일러와 함께 사용하기 위한 NEON 내장 함수

이 단원에서는 이러한 내장 함수 계열에 대해 설명합니다.

4.1.1 내장 함수 개요

C 및 C++는 다양한 연산에 사용할 수 있지만 DSP(디지털 신호 처리)와 같은 일부 응용 프로그램에 대해서는 자체적인 지원을 제공하지 않습니다.

일반적으로 특정 응용 프로그램 도메인 내에는 빈번하게 수행해야 하는 다양한 도메인 관련 연산이 있습니다. 그러나 C 또는 C++에서는 이러한 연산이 종종 효율적으로 구현되지 않을 수 있습니다. 이러한 연산의 대표적인 예로 DSP 프로그래밍에 주로 사용되는 32비트 부호 있는 2의 보수 정수 두 개에 대한 포화된 더하기를 들 수 있습니다. 예제 4-1에서는 C에서 이러한 연산을 구현한 것을 보여 줍니다.

예제 4-1 C의 포화된 더하기 연산 구현

#include <limits.h>int L_add(const int a, const int b){

int c;c = a + b;if (((a ^ b) & INT_MIN) == 0){

if ((c ^ a) & INT_MIN){

c = (a < 0) ? INT_MIN : INT_MAX;}

}return c;

}

4-2 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 79: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

내장 함수를 사용하면 임베디드 어셈블러나 인라인 어셈블러 등에서 복잡한 구현으로 재정렬하지 않고도 C 및 C++ 소스 코드에서 도메인 관련 연산을 손쉽게 통합할 수 있습니다. 내장 함수는 C 또는 C++의 함수 호출과 비슷하지만 컴파일하는 동안 하위 수준 명령어의 특정 시퀀스로 대체됩니다. 예를 들어 내장 함수를 사용하여 4-2페이지의 예제 4-1의 포화된 더하기 함수를 구현할 경우 다음과 같은 형식이 사용됩니다.

#include <dspfns.h> /* Include ETSI intrinsics */...int a, b, result;...result = L_add(a, b); /* Saturated add of a and b */

내장 함수를 사용하면 다음과 같은 여러 가지 성능 향상 효과를 얻을 수 있습니다.

• 하위 수준 명령어를 내장 함수로 대체하면 하위 수준 명령어를 C 또는 C++에서 구현할 때보다 더 효율적이기 때문에 명령어 및 사이클 수가 모두 감소합니다. 내장 함수를 구현하기 위해 컴파일러는 지정된 타겟 아키텍처에 대한 최상의 명령어 시퀀스를 자동으로 생성합니다. 예를 들어 L_add 내장 함수가 ARM v5TE 어셈블리 언어 명령어 qadd로 직접 매핑됩니다.

QADD r0, r0, r1 /* Assuming r0 = a, r1 = b on entry */

• 내부 C 및 C++ 언어에 포함할 수 있는 것보다 많은 정보가 컴파일러에 제공됩니다. 이렇게 하면 컴파일러에서 다른 방식으로는 수행할 수 없는 최적화 작업을 수행하고 명령어 시퀀스를 생성할 수 있습니다.

이러한 성능 향상 효과는 실시간 처리 응용 프로그램의 성능을 크게 향상시킬 수 있습니다. 그러나 코드 이식성이 저하될 수 있으므로 내장 함수를 사용할 때는 주의를 기울여야 합니다.

4.1.2 명령어 내장 함수

ARM 컴파일러는 C 또는 C++ 코드에서 ARM 어셈블리 언어 명령어를 인식하는 데 필요한 다양한 명령어 내장 함수를 제공합니다. 이러한 내장 함수를 사용하면 C 코드 및 명령어 내장 함수의 조합을 통해 인라인 어셈블리 코드를 에뮬레이션할 수 있습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 4-3ID090708 Non-Confidential, Unrestricted Access

Page 80: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

일반 내장 함수

컴파일러 참조 설명서에서는 ISO C 및 C++ 표준에 대한 ARM 언어 확장인 다음과 같은 일반 내장 함수를 설명합니다.

• 4-77페이지의 __breakpoint

• 4-79페이지의 __current_pc

• 4-80페이지의 __current_sp

• 4-90페이지의 __nop

• 4-97페이지의 __return_address

• 4-99페이지의 __semihost

또한 컴파일러 참조 설명서에서 4-120페이지의 GNU 기본 제공 함수를 추가로 참조하십시오.

이러한 내장 함수의 구현은 모든 아키텍처에서 사용할 수 있습니다.

IRQ 및 FIQ 인터럽트 제어용 내장 함수

컴파일러 참조 설명서에서는 IRQ 및 FIQ 인터럽트를 제어할 수 있도록 하는 다음과 같은 내장 함수를 설명합니다.

• 4-82페이지의 __disable_irq

• 4-83페이지의 __enable_irq

• 4-81페이지의 __disable_fiq

• 4-83페이지의 __enable_fiq

이러한 내장 함수를 사용하여 모드, 상태 및 부정확한 데이터 중단 설정을 비롯한 다른 모든 CPSR 비트를 변경할 수 없습니다. 따라서 CPSR 및 SPSR의 제어 비트는 사용자 모드에서 변경할 수 없기 때문에 프로세서가 권한 모드에 있을 경우에만 내장 함수를 사용할 수 있습니다.

이 내장 함수는 ARM 및 Thumb 상태의 모든 프로세서 아키텍처에서 사용 가능합니다.

• ARMv6(또는 이후 버전)을 지원하는 프로세서에 대해 컴파일하는 경우 이 함수에 대해 CPS 명령어가 인라인으로 생성됩니다. 예를 들면 다음과 같습니다.

CPSID i

4-4 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 81: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

• ARM 상태의 ARMv4 또는 ARMv5를 지원하는 프로세서에 대해 컴파일하는 경우, 컴파일러는 MRS 및 MSR 명령어의 시퀀스를 인라인합니다. 예를 들면 다음과 같습니다.

MRS r0, CPSR ORR r0, r0, #0x80 MSR CPSR_c, r0

• Thumb 상태의 ARMv4 또는 ARMv5를 지원하는 프로세서에 대해 컴파일하는 경우, 컴파일러는 도우미 함수를 호출합니다. 예를 들면 다음과 같습니다.

BL __ARM_disable_irq

이러한 명령어에 대한 자세한 내용은 어셈블러 설명서를 참조하십시오.

최적화 장벽 삽입용 내장 함수

ARM 컴파일러는 명령어 순서 변경, 일부 연산의 병합 등 다양한 최적화 작업을 수행할 수 있습니다. 메모리가 다중 프로세스에 의해 동시에 액세스되는 시스템 수준 프로그래밍과 같은 경우, 명령어 순서 변경 비활성화 및 메모리 강제 업데이트가 필요할 수도 있습니다.

다음 최적화 장벽 내장 함수는 코드를 생성하지 않지만, 코드 크기가 약간 커지고 메모리 액세스가 추가되는 결과를 가져올 수 있습니다. 컴파일러 참조 설명서에서 다음을 참조하십시오.

• 4-98페이지의 __schedule_barrier

• 4-85페이지의 __force_stores

• 4-90페이지의 __memory_changed

참고

일부 시스템에서 메모리 장벽 내장 함수는 메모리 일관성을 보장할 정도로 충분하지 않을 수도 있습니다. 예를 들어 __memory_changed() 내장 함수는 레지스터에 있는 값을 메모리로 강제로 보냅니다. 그러나 데이터의 목적지가 버퍼링될 수 있는 영역에 있다면, 작성 버퍼에서 대기할 수도 있습니다. 이 경우 CP15에 기록하거나 메모리 장벽 명령어를 사용하여 작성 버퍼를 고갈시켜야할 수도 있습니다. 자세한 내용은 ARM 프로세서의 기술 참조 문서를 참조하십시오.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 4-5ID090708 Non-Confidential, Unrestricted Access

Page 82: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

네이티브 명령어 삽입용 내장 함수

다음 내장 함수를 사용하면 컴파일러가 생성한 명령어 스트림에 ARM 프로세서 명령어를 삽입할 수 있습니다. 컴파일러 참조 설명서에서 다음을 참조하십시오.

• 4-78페이지의 __cdp

• 4-78페이지의 __clrex

• 4-85페이지의 __ldrex

• 4-88페이지의 __ldrt

• 4-91페이지의 __pld

• 4-93페이지의 __pli

• 4-95페이지의 __rbit

• 4-96페이지의 __rev

• 4-98페이지의 __ror

• 4-101페이지의 __sev

• 4-103페이지의 __strex

• 4-106페이지의 __strt

• 4-107페이지의 __swp

• 4-109페이지의 __wfe

• 4-110페이지의 __wfi

• 4-111페이지의 __yield

디지털 신호 처리용 내장 함수

컴파일러 참조 설명서에 설명되어 있는 다음 내장 함수는 DSP 알고리즘의 구현에 사용할 수 있습니다.

• 4-79페이지의 __clz

• 4-84페이지의 __fabs

• 4-84페이지의 __fabsf

• 4-94페이지의 __qadd

• 4-94페이지의 __qdbl

• 4-95페이지의 __qsub

• 4-101페이지의 __sqrt

• 4-102페이지의 __sqrtf

• 4-102페이지의 __ssat

• 4-108페이지의 __usat

4-6 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 83: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

또한 컴파일러 참조 설명서에서 4-111페이지의 ARMv6 SIMD 내장 함수를 추가로 참조하십시오.

이러한 내장 함수는 다음에 대한 적절한 타겟 명령어를 만듭니다.

• ARM v5TE 이후의 ARM 아키텍처

• 'M' 변형을 제외한 Thumb-2 아키텍처

모든 명령어에 자체 내장 함수가 있는 것은 아닙니다. 컴파일러는 다양한 내장 함수 또는 내장 함수와 C 연산자를 조합하여 보다 강력한 명령어를 생성할 수 있습니다. 예를 들어 ARM5TE QDADD 명령어는 __qadd 및 __qdbl의 조합으로 인식됩니다.

4.1.3 ETSI 기본 연산

ETSI(유럽 통신 표준 협회)에서는 G.723.1 및 G.729 권장 사항과 같은 음성 코딩과 관련된 여러 가지 권장 사항을 만들었습니다. 이러한 권장 사항에는 코덱의 참조 구현을 위한 소스 코드와 테스트 시퀀스가 포함되어 있습니다.

ETSI에서 제공하는 음성 코덱의 모델 구현은 ETSI 기본 연산이라고 하는 C 함수의 컬렉션을 기반으로 합니다. ETSI 기본 연산에는 포화된 산술용 16비트, 32비트 및 40비트 연산, 16비트 및 32비트 논리 연산 및 데이터 유형 변환용 16비트 및 32비트 연산이 있습니다.

참고

ITU-T Software Tool Library 2005 User's manual에 설명된 대로 2.0 버전의 ETSI 기본 연산 컬렉션에는 새로운 16비트, 32비트 및 40비트 연산이 도입되었습니다. 이러한 연산은 RVCT에서 지원되지 않습니다.

ETSI 기본 연산은 C 또는 C++에서 코덱을 구현하는 개발자가 사용하기 위한 라이브러리가 아니라 코덱 알고리즘을 게시하는 개발자의 기본 연산 세트 역할을 합니다. RVCT는 헤더 파일 dspfns.h를 통해 ETSI 기본 연산을 지원합니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 4-7ID090708 Non-Confidential, Unrestricted Access

Page 84: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

RVCT에서의 ETSI 연산

dspfns.h 헤더 파일에는 ETSI 기본 연산의 정의가 C 코드 및 내장 함수의 조합으로 포함되어 있습니다. RVCT는 ETSI G.729 권장 사항 CS-ACELP(conjugate-structure algebraic-code-excited linear prediction)를 사용하여 8kbit/s로 음성 코딩에 설명되어 있는 원래 ETSI 계열의 기본 작업을 지원합니다. 이러한 기본 작업은 다음과 같습니다.

• add 및 sub 같은 16비트 및 32비트 포화된 산술 연산. 예를 들어 add(v1, v2)는 오버플로 제어 및 포화를 사용하여 두 개의 16비트 숫자 v1과 v2를 더하고 16비트 결과를 반환합니다.

• 및 L_mult 같은 16비트 및 32비트 곱하기 연산. 예를 들어 mult(v1, v2)는 두 개의 16비트 숫자 v1과 v2를 곱하고 스케일된 16비트 결과를 반환합니다.

• shl 및 shr 같은 16비트 산술 시프트 연산. 예를 들어 포화 왼쪽으로 시프트 연산 shl(v1, v2)는 16비트 입력 v1을 왼쪽으로 v2 위치만큼 산술 시프트합니다. 음의 시프트 횟수는 v1을 오른쪽으로 v2 위치만큼 시프트합니다.

• extract_l, extract_h 및round 같은 16비트 데이터 변환 연산. 예를 들어 round(L_v1)은 포화를 사용하여 32비트 입력 L_v1의 하위 16비트를 최상위 16비트로 반올림합니다.

참고

dspfns.h 헤더 파일과 ISO C99 헤더 파일 math.h는 둘 다 round() 함수(버전은 다름)를 정의하므로 충돌이 발생하지 않도록 주의하십시오.

RVCT에서 지원되는 ETSI 기본 연산의 전체 목록을 보려면 헤더 파일 dspfns.h를 참조하십시오.

또한 다음을 참조하십시오.

• ETSI Recommendation G.191: 음성 및 오디오 코딩 표준화를 위한 소프트웨어 도구

• ITU-T Software Tool Library 2005 User's manual(ETSI 권장 사항 G.191의 일부로 포함)

• ETSI Recommendation G723.1: 5.3 및 6.3kbit/s로 전송되는 멀티미디어 통신용 이중 속도 음성 코더

• ETSI Recommendation G.729: CS-ACELP(Conjugate-Structure Algebraic-Code-Excited Linear Prediction)를 사용하여 8kbit/s의 속도로 코딩

4-8 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 85: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

이러한 문서는 ITU의 전기 통신 안내소인 ITU-T(http://www.itu.int)에서 구할 수 있습니다.

오버플로 및 캐리

dspfns.h에서 ETSI 기본 연산을 구현하면 상태 플래그 Overflow 및 Carry가 표시됩니다. 이러한 플래그는 사용자의 자체 C 또는 C++ 프로그램에서 전역 변수로 사용할 수 있습니다. 예를 들면 다음과 같습니다.

#include <dspfns.h> /* include ETSI intrinsics */#include <stdio.h>...const int BUFLEN=255;int a[BUFLEN], b[BUFLEN], c[BUFLEN];...Overflow = 0; /* clear overflow flag */for (i = 0; i < BUFLEN; ++i) {

c[i] = L_add(a[i], b[i]); /* saturated add of a[i] and b[i] */}if (Overflow){

fprintf(stderr, "Overflow on saturated addition\n");}

일반적으로 포화 함수에서 오버플로에 대한 까다로운 결과입니다. 즉, 오버플로 플래그는 명시적으로 지울 때까지 설정된 상태로 있습니다. 자세한 내용은 헤더 파일 dspfns.h를 참조하십시오.

4.1.4 TI C55x 내장 함수

TI(Texas Instruments) C55x 컴파일러는 C 코드의 최적화 작업을 위한 다양한 내장 함수를 인식합니다. RVCT는 헤더 파일 c55x.h를 통해 선택한 TI C55x 내장 함수의 에뮬레이션을 지원합니다. c55x.h에 에뮬레이션된 TI C55x 내장 함수에는 다음이 포함됩니다.

• _sadd 및 _ssub 같은 더하기, 빼기, 부정 및 절대값에 사용되는 내장 함수. 예를 들어 _sadd(v1, v2)는 v1 및 v2의 16비트 포화된 합계를 반환합니다.

• _smpy 및 _sshl 같은 곱하기 및 시프트에 사용되는 내장 함수. 예를 들어 _smpy(v1, v2)는 v1 및 v2의 포화된 분수식 결과를 반환합니다.

• _round 및 _count 같은 반올림, 포화, 비트 계산 및 극값에 사용되는 내장 함수. 예를 들어 _round(v1)은 포화되지 않은 산술을 통해 215를 더하고 하위 16비트를 지워 반올림된 v1을 반환합니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 4-9ID090708 Non-Confidential, Unrestricted Access

Page 86: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

다음 TI C55x 내장 함수는 c55x.h에서 지원되지 않습니다.

• 더하기 및 곱하기 누산에 사용되는 내장 함수의 연관 변형. 여기에는 _a_sadd 및 _a_smac 같이 접두사로 _a_가 지정된 모든 TI C55x 내장 함수가 포함됩니다.

• _smacr 및 _smasr 같이 곱하기 및 시프트에 사용되는 내장 함수의 반올림 변형

• 내장 함수의 모든 long long 변형. 여기에는 _llsadd 및 _llshl 같이 접두사로 _ll가 지정된 모든 TI C55x 내장 함수가 포함됩니다. 내장 함수의 long long 변형은 40비트 데이터에 대해 작동하므로 RVCT에서 지원되지 않습니다.

• 부작용이 있는 모든 산술 내장 함수. 예를 들어 TI C55x 내장 함수 _firs 및 _lms는 c55x.h에 정의되어 있지 않습니다.

• L_add_c 및 L_sub_c 같은 ETSI 지원 함수에 사용되는 내장 함수

참고

예외적으로 포화 나누기 divs에 대한 ETSI 지원 함수는 c55x.h에서 지원됩니다.

RVCT에 에뮬레이션된 TI C55x 내장 함수의 전체 목록을 보려면 헤더 파일 c55x.h를 참조하십시오.

TI 컴파일러 내장 함수에 대한 자세한 내용은 http://www.ti.com을 참조하십시오.

4.1.5 명명된 레지스터 변수

컴파일러를 사용하면 명명된 레지스터 변수를 사용하는 ARM 아키텍처 기반 프로세서의 레지스터에 액세스할 수 있습니다.

명명된 레지스터 변수는 register 키워드와 __asm 키워드를 결합하여 선언됩니다. __asm 키워드는 레지스터 이름에 사용되는 문자열인 하나의 매개변수를 사용합니다. 예를 들어 다음과 같이 선언됩니다.

register int R0 __asm("r0");

R0를 레지스터 r0의 명명된 레지스터 변수로 선언합니다. 명명된 레지스터 변수를 통해 액세스할 수 있는 ARM 아키텍처 기반 프로세서의 레지스터에 대한 자세한 내용은 컴파일러 참조 설명서에서 4-116페이지의 명명된 레지스터 변수를 참조하십시오.

4-10 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 87: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

일반적으로 명명된 레지스터 변수는 APSR( 응용 프로그램 상태 레지스터)의 비트에 액세스하는 데 사용됩니다. 어셈블러 설명서의 2-8페이지의 APSR (응용 프로그램 상태 레지스터)를 참조하십시오. 예제 3-3에서는 명명된 레지스터 변수를 사용하여 APSR에 포화 플래그 Q를 설정하는 방법을 보여 줍니다.

예제 4-2 명명된 레지스터 변수를 통해 APSR의 비트 설정

#ifndef __BIG_ENDIAN // bitfield layout of APSR is sensitive to endiannesstypedef union{

struct{

int mode:5;int T:1;int F:1;int I:1;int _dnm:19;int Q:1;int V:1;int C:1;int Z:1;int N:1;

} b;unsigned int word;

} PSR;#else /* __BIG_ENDIAN */typedef union{

struct {

int N:1;int Z:1;int C:1;int V:1;int Q:1;int _dnm:19;int I:1;int F:1;int T:1;int mode:5;

} b;unsigned int word;

} PSR;#endif /* __BIG_ENDIAN */register PSR apsr __asm("apsr");void set_Q(void)

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 4-11ID090708 Non-Confidential, Unrestricted Access

Page 88: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

{apsr.b.Q = 1;

}

4.1.6 NEON 내장 함수

ARM 컴파일러에서는 NEON 내장 함수를 사용하여 컴파일러 벡터화 단계와 어셈블러 코드 작성 단계 사이에서 SIMD 코드를 생성하는 중간 단계를 사용할 수 있습니다. 이 기능을 사용하면 어셈블러를 직접 작성할 때보다 NEON 아키텍처를 사용하는 코드를 더 쉽게 작성할 수 있습니다.

NEON 내장 함수는 헤더 파일 arm_neon.h에 정의되어 있습니다. 헤더 파일은 내장 함수와 벡터 유형 세트를 모두 정의합니다. NEON 내장 함수에 대한 자세한 내용은 컴파일러 참조 설명서에서 부록 E NEON 지원 사용을 참조하십시오.

예제 4-3에서 NEON 내장 함수를 사용하는 간단한 예를 보여 줍니다. 예제를 빌드하려면 다음을 수행하십시오.

1. 다음 옵션을 지정하여 C 파일 neon_example.c를 컴파일합니다.

armcc -c --debug --cpu=Cortex-A8 neon_example.c

2. 다음 명령을 사용하여 이미지를 링크합니다.

armlink neon_example.o -o neon_example.axf

3. RealView 디버거와 같은 호환되는 디버거를 사용하여 이미지를 로드하고 실행합니다.

예제 4-3 NEON 내장 함수

/* 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

4-12 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 89: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

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;

}

NEON에 대한 자세한 내용은 다음을 참조하십시오.

• 2-25페이지의 NEON 기술

• 어셈블러 설명서

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 4-13ID090708 Non-Confidential, Unrestricted Access

Page 90: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

4.2 Pragma

ARM 컴파일러는 다음 형식의 pragma를 인식합니다.

#pragma no_feature-name

#pragma feature_name

참고

Pragma는 관련 명령 행 옵션을 재정의합니다. 예를 들어 #pragma arm은 --thumb 명령 행 옵션을 재정의합니다.

자세한 내용은 컴파일러 참조 설명서에서 관련 단원을 참조하십시오.

pragma 상태를 저장하고 복원하기 위한 pragma

다음 pragma를 사용하면 pragma 상태를 저장하고 복원할 수 있습니다.

• 4-71페이지의 #pragma pop

• 4-71페이지의 #pragma push

최적화 목표를 제어하는 pragma

이 pragma를 사용하면 각 함수에 최적화 목표를 할당할 수 있습니다. pragma는 함수 외부에 배치해야 합니다. 다음 pragma는 이러한 최적화 작업을 제어합니다.

• 4-68페이지의 #pragma Onum

• 4-69페이지의 #pragma Ospace

• 4-69페이지의 #pragma Otime

코드 생성을 제어하는 pragma

다음 pragma는 코드 생성 방법을 제어합니다.

• 4-59페이지의 #pragma arm

• 4-75페이지의 #pragma thumb

• 4-65페이지의 #pragma exceptions_unwind, #pragma no_exceptions_unwind

루프 언롤링을 제어하는 pragma

다음 pragma는 루프 언롤링 방법을 제어합니다.

• 4-72페이지의 #pragma unroll [(n)]

• 4-74페이지의 #pragma unroll_completely

4-14 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 91: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

PCH(사전 컴파일된 헤더) 처리를 제어하는 pragma

다음 pragma는 PCH 처리를 제어합니다.

• 4-65페이지의 #pragma hdrstop

• 4-67페이지의 #pragma no_pch

익명 구조체 및 공용체를 제어하는 pragma

다음 pragma는 익명 구조체 및 공용체의 사용을 제어합니다.

• 4-59페이지의 #pragma anon_unions, #pragma no_anon_unions

진단 메시지를 제어하는 pragma

다음 pragma는 메시지 번호에 -D 접미사가 있는 진단 메시지의 출력을 제어합니다.

• 4-61페이지의 #pragma diag_default tag[,tag,...]

• 4-62페이지의 #pragma diag_error tag[,tag,...]

• 4-63페이지의 #pragma diag_remark tag[,tag,...]

• 4-64페이지의 #pragma diag_suppress tag[,tag,...]

• 4-64페이지의 #pragma diag_warning tag[, tag, ...]

기타 pragma

• 4-59페이지의 #pragma arm section [section_sort_list]

• 4-66페이지의 #pragma import(__use_full_stdio)

• 4-67페이지의 #pragma inline, #pragma no_inline

• 4-68페이지의 #pragma once

• 4-69페이지의 #pragma pack(n)

• 4-71페이지의 #pragma softfp_linkage, #pragma no_softfp_linkage

• 4-66페이지의 #pragma import symbol_name

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 4-15ID090708 Non-Confidential, Unrestricted Access

Page 92: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

4.3 비트 밴딩

이 단원에서는 컴파일러에서 비트 밴딩 기능을 지원하는 방법에 대해 설명합니다.

참고

비트 밴딩은 Cortex-M3 프로세서 및 일부 파생 프로세서에서 제공되는 기능입니다. 다른 ARM 프로세서에서는 이 기능을 제공하지 않습니다.

비트 밴딩 기능을 지원하는 아키텍처인지 확인하려면 해당 프로세서의 기술 참조 문서를 참조하십시오.

비트 밴딩은 다음과 같은 방식으로 지원됩니다.

• __attribute__((bitband)) 언어 확장

• --bitband 명령 행 옵션

4.3.1 __attribute__((bitband)) 사용

__attribute__((bitband))는 bitband 형식의 구조체 정의에 사용되는 형식 속성입니다. 예제 4-4 및 4-17페이지의 예제 4-5를 참조하십시오.

예제 4-4 배치되지 않은 객체

/* foo.c */

typedef struct {int i : 1;int j : 2;int k : 3;

} BB __attribute__((bitband));

BB value; // Unplaced object

void update_value(void){

value.i = 1;value.j = 0;

}

/* end of foo.c */

4-16 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 93: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

4-16페이지의 예제 4-4에서 배치되지 않은 비트 밴딩 객체는 비트 밴딩 영역으로 재배치되어야 합니다. 그러려면 해당 분산 로드 설명 파일이나 --rw_base 링커 명령 행 옵션을 사용해야 합니다. 자세한 내용은 링커 참조 설명서를 참조하십시오.

또는 __attribute__((at()))를 사용하여 비트 밴딩 객체를 비트 밴딩 영역의 특정 주소로 배치할 수도 있습니다.. 자세한 내용은 예제 4-5를 참조하십시오.

예제 4-5 배치된 객체

/* foo.c */

typedef struct {int i : 1;int j : 2;int k : 3;

} BB __attribute__((bitband));

BB value __attribute__((at(0x20000040))); // Placed object

void update_value(void){

value.i = 1;value.j = 0;

}

/* end of foo.c */

자세한 내용은 컴파일러 참조 설명서에서 4-44페이지의 __attribute__((bitband)) 및 4-50페이지의 __attribute__((at(address)))을 참조하십시오.

4.3.2 명령 행에서 --bitband 사용

--bitband 명령 행 옵션은 생성자 전역 구조 객체가 아닌 모든 객체에 대해 비트 밴딩을 수행합니다.

4-18페이지의 예제 4-6에서 foo.c에 --bitband 옵션을 적용하게 되면 value.i로의 쓰기 작업이 비트 밴딩됩니다. 즉, value.i를 비트 밴딩 영역으로 매핑하는 비트 밴딩 별칭 단어에 0x00000001 값이 기록됩니다.

value.j 및 value.k 에 대한 액세스는 비트 밴딩되지 않습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 4-17ID090708 Non-Confidential, Unrestricted Access

Page 94: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

예제 4-6 --bitband 명령 행 옵션 사용

/* foo.c */

typedef struct {int i : 1;int j : 2;int k : 3;

} BB;

BB value __attribute__((at(0x20000040))); // Placed object

void update_value(void){

value.i = 1;value.j = 0;

}

/* end of foo.c */

armcc는 절대 주소로 액세스된 객체의 비트 밴딩을 지원합니다. 예제 4-7에서 foo.c에 --bitband 옵션이 적용되면 rts 에 대한 액세스가 비트 밴딩됩니다.

예제 4-7 절대 주소로 액세스된 객체의 비트 밴딩

/* foo.c */

typedef struct {int rts : 1;int cts : 1;unsigned int data;

} uart;

#define com2 (*((volatile uart *)0x20002000))void put_com2(int n) {com2.rts = 1;com2.data = n;

}

/* end of foo.c */

4-18 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 95: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

자세한 내용은 컴파일러 참조 설명서의 2-19페이지의 --bitband를 참조하십시오.

4.3.3 제한

다음 제한이 적용됩니다.

• 비트 밴딩은 구조체 형식으로만 사용될 수 있습니다. 모든 공용체 또는 공용체를 구성원으로 포함하는 집계 형식은 비트 밴딩할 수 없습니다.

• 구조체 구성원은 개별적으로 비트 밴딩할 수 없습니다.

• 단일 비트의 비트 필드에 대해서만 비트 밴딩 액세스가 생성됩니다.

• 생성자 객체, 포인터 및 지역 개체에 대해서는 비트 밴딩 액세스가 생성되지 않습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 4-19ID090708 Non-Confidential, Unrestricted Access

Page 96: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

4.4 스레드-지역 스토리지

TLS(스레드-로컬 저장소)는 정적 저장소 클래스로서 스택처럼 실행 스레드마다 고유합니다. 프로세스의 각 스레드에는 스레드 관련 데이터를 저장할 수 있는 위치가 제공됩니다. 변수는 각 기존 스레드에 하나의 변수 인스턴스가 있도록 할당됩니다.

각 스레드는 종료되기 전에 동적 메모리를 해제하며, 이 스레드의 스레드-지역 변수를 가리키는 포인터는 무효가 됩니다.

컴파일러 참조 설명서의 4-32페이지의 __declspec(thread)를 참조하십시오.

4-20 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 97: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

4.5 8바이트 정렬 기능

ARM 컴파일러에는 다음과 같은 8바이트 정렬 기능이 있습니다.

• AAPCS(ARM 아키텍처용 프로시저 호출 표준)에 따라 스택은 모든 외부 인터페이스에서 8바이트 단위로 정렬됩니다. ARM 컴파일러와 C 라이브러리는 스택의 8바이트 정렬을 유지합니다. 또한 기본 C 라이브러리 메모리 모델도 스택의 8바이트 정렬을 유지합니다.

• 코드는 외부 인터페이스에서 8바이트 정렬 제약 조건을 요구 및 보존하는 방식으로 컴파일됩니다.

• 프로젝트에 어셈블리 파일이나 레거시 객체 또는 라이브러리가 있으면 이들이 8바이트 정렬을 유지하는지 확인하고 필요한 경우 이들을 수정해야 합니다. 어셈블러 설명서 및 링커 사용 설명서를 참조하십시오.

• RVCT v2.0 이상에서는 double 및 long long 데이터 형식이 8바이트 단위로 정렬됩니다. 따라서 ARMv5TE 이상에서 LDRD 및 STRD 명령어를 효율적으로 사용할 수 있습니다.

• malloc(), realloc() 및 calloc()의 기본 구현은 8바이트 단위로 정렬된 힙을 유지 관리합니다.

• alloca()의 기본 구현은 8바이트 단위로 정렬되는 메모리 블록을 반환합니다. 이 C 라이브러리 확장에 대한 자세한 내용은 라이브러리 설명서에서 2-76페이지의 alloca()를 참조하십시오.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 4-21ID090708 Non-Confidential, Unrestricted Access

Page 98: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

컴파일러 기능

4-22 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 99: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

5장 코딩 방법

ARM 컴파일러 armcc는 고도로 최적화된 기계어 코드를 생성할 수 있는 고성능 ISO C 및 C++ 컴파일러입니다. ARM 코어와 같은 RISC 프로세서에서 잘 작동하는 프로그래밍 방법과 기술을 사용하면 C 및 C++ 소스 코드의 이식성, 효율성 및 견고성을 향상시킬 수 있습니다. 이 장에서는 이러한 프로그래밍 방법과 함께 ARM 프로세서에 특정적인 프로그래밍 기술에 대해 설명합니다.

이 장은 다음 단원으로 구성되어 있습니다.

• 5-2페이지의 코드 최적화

• 5-10페이지의 코드 메트릭스

• 5-13페이지의 함수

• 5-18페이지의 함수 인라인

• 5-26페이지의 데이터 정렬

• 5-33페이지의 부동 소수점 산술 사용

• 5-42페이지의 0으로 나누기 오류 트래핑 및 확인

• 5-47페이지의 C99의 새로운 기능

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-1ID090708 Non-Confidential, Unrestricted Access

Page 100: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

5.1 코드 최적화

ARM 컴파일러는 크기를 작게 하고 성능을 향상시키기 위해 코드를 높은 수준으로 최적화합니다. ARM 컴파일러는 공통 하위식 제거 같은 데이터 흐름 최적화와 루프 결합 및 배포 같은 루프 최적화 등 타사 최적화 컴파일러에서 공통적으로 지원되는 최적화뿐만 아니라 ARM 아키텍처 기반 프로세서에 고유한 다양한 최적화를 수행합니다.

컴파일러 자체에서 코드를 높은 수준으로 최적화하지만, 올바른 최적화 기준, 타겟 프로세서 및 아키텍처, 인라인 옵션 등을 선택하여 C 또는 C++ 코드의 성능을 한층 더 향상시킬 수 있습니다.

5.1.1 크기 및 속도 최적화

컴파일러에는 코드 크기와 성능을 최적화하기 위한 다음 두 가지 옵션이 있습니다.

-Ospace 이 옵션을 선택하면 컴파일러가 주로 코드 크기를 최적화합니다. 기본 옵션입니다.

-Otime 이 옵션을 선택하면 컴파일러가 주로 속도를 최적화합니다.

최상의 결과를 얻으려면 가장 적절한 명령 행 옵션을 사용하여 응용 프로그램을 빌드해야 합니다.

참고

이러한 명령 행 옵션은 대부분의 경우에 원하는 효과를 제공하는 최적화를 사용하도록 컴파일러에 지시합니다. 그러나 -Otime이 항상 더 빠른 코드를 생성하거나 -Ospace가 항상 더 작은 코드를 생성하지는 않습니다.

다음을 참조하십시오.

• 컴파일러 참조 설명서의 2-104페이지의 -Ospace

• 컴파일러 참조 설명서의 2-105페이지의 -Otime

5.1.2 최적화 수준 및 디버그 뷰

컴파일러가 수행하는 정확한 최적화는 선택한 최적화 수준과 최적화 대상이 성능인지 아니면 코드 크기인지에 따라 다릅니다.

5-2 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 101: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

컴파일러는 다음과 같은 최적화 수준을 지원합니다.

-O0 최소 최적화. 컴파일러에서 디버그 뷰를 손상시키지 않는 간단한 최적화를 수행합니다.

디버깅을 사용할 경우 이 옵션은 최상의 디버그 뷰를 제공합니다.

-O1 제한적 최적화

디버깅을 사용할 경우 이 옵션은 코드가 한결 간결해진 만족스러운 디버그 뷰를 제공합니다.

-O2 높은 최적화. 이것이 기본 최적화 수준입니다.

디버깅을 사용할 경우 이 옵션은 다소 만족스럽지 않은 디버그 뷰를 제공할 수 있습니다.

-O3 최대 최적화. 가장 적극적인 최적화입니다. 이 옵션을 지정하면 명령 행에 여러 개의 파일을 지정하는 다중 파일 컴파일을 기본적으로 사용할 수 있습니다.

디버깅을 사용할 경우 이 옵션은 일반적으로 낮은 수준의 디버그 뷰를 제공합니다.

최적화는 객체 코드를 소스 코드로 매핑하는 데 영향을 주기 때문에 일반적으로 최적화 수준 및 -Ospace/-Otime의 선택은 디버그 뷰에 영향을 줍니다. --debug를 통해 디버깅을 사용하도록 설정할 경우 -Onum 명령 행 옵션을 사용하여 가장 적절한 최적화 수준을 명시적으로 지정하십시오.

-O0 옵션은 단순 디버그 뷰가 필요한 경우에 사용할 수 있는 가장 좋은 옵션입니다. 일반적으로 -O0을 선택하면 ELF 이미지의 크기가 7-15% 정도 증가합니다. 디버그 테이블의 크기를 줄이려면 --no_debug_macros 옵션을 사용하십시오.

다음을 참조하십시오.

• 컴파일러 참조 설명서의 2-39페이지의 --debug, --no_debug

• 컴파일러 참조 설명서의 2-39페이지의 --debug_macros, --no_debug_macros

• 컴파일러 참조 설명서의 2-54페이지의 --dwarf2

• 컴파일러 참조 설명서의 2-54페이지의 --dwarf3

• 컴파일러 참조 설명서의 2-102페이지의 -Onum

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-3ID090708 Non-Confidential, Unrestricted Access

Page 102: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

5.1.3 타겟 CPU 선택

일반적으로 새 ARM 아키텍처 버전이 나올 때마다 추가 명령어, 연산 모드, 다른 파이프라인 및 레지스터 이름 바꾸기가 지원됩니다.

• 컴파일된 프로그램이 특정 ARM 아키텍처 기반 프로세서에서 실행하기 위한 것일 경우 --cpu 명령 행 옵션을 사용하여 타겟 프로세서를 선택하는 것이 좋습니다. 그러면 컴파일러는 프로세서가 지원하는 명령어를 최대한 활용하고 명령어 일정과 같은 프로세서 관련 최적화를 수행할 수 있습니다.

• 컴파일된 프로그램이 다른 ARM 프로세서에서 실행하기 위한 것일 경우 --cpu 명령 행 옵션을 사용하여 응용 프로그램에 적합한 최소 공분모 아키텍처를 선택해야 합니다. 예를 들어 ARM v6 아키텍처를 지원하는 프로세서에 대한 코드를 컴파일하려면 명령 행 옵션 --cpu 6을 사용합니다.

참고

명령 행 옵션 --cpu list를 사용하여 컴파일러가 지원하는 프로세서와 아키텍처를 모두 나열할 수 있습니다.

다음을 참조하십시오.

• 2-24페이지의 타겟 프로세서 또는 아키텍처 지정

• 컴파일러 참조 설명서의 2-32페이지의 --cpu=list

• 컴파일러 참조 설명서의 2-32페이지의 --cpu=name

5.1.4 루프 최적화

루프는 대부분의 프로그램에서 공통적으로 사용되는 구성요소입니다. 많은 양의 실행 시간이 루프에 할애되기 때문에 시간이 중요한 루프에 주의를 기울이는 것이 좋습니다.

루프 종료

루프 종료 조건을 부주의하게 작성하면 상당한 오버헤드가 발생할 수 있습니다. 가능하면 다음과 같이 하는 것이 좋습니다.

• 항상 0으로 카운트다운 루프를 작성하고 단순 종료 조건을 사용합니다.

• 항상 unsigned int 유형의 카운터를 사용하고 0과 같지 않은지 테스트합니다.

5-4 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 103: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

표 5-1에서는 n!을 계산하기 위한 루틴의 두 가지 샘플 구현을 보여 줍니다. 두 가지 모두 루프 종료 오버헤드가 나타나 있습니다. 첫 번째 구현은 증가 루프를 사용하여 n!을 계산하는 반면 두 번째 루틴은 감소 루프를 사용하여 n!을 계산합니다.

표 5-2에서는 표 5-1의 각 샘플 구현에 대해 컴파일러에서 생성된 기계어 코드의 디스어셈블리를 보여 줍니다. 여기서 이 두 가지 구현을 위한 C 코드는 -O2 -Otime 옵션을 사용하여 컴파일되었습니다.

표 5-2의 디스어셈블리를 비교하면 증가 루프 어셈블리의 ADD/CMP 명령어 쌍이 감소 루프 디스어셈블리의 단일 SUBS 명령어로 대체되었다는 것을 알 수 있습니다. 이것은 최적화를 통해 0과의 비교를 제거할 수 있기 때문입니다.

명령어를 루프에 저장하는 것 이외에 변수 n을 루프에 걸쳐 저장할 필요가 없기 때문에 레지스터의 사용이 감소 루프 디스어셈블리에도 저장됩니다. 따라서 레지스터 할당이 쉬워집니다.

표 5-1 증가 및 감소 루프에 대한 C 코드

증가 루프 감소 루프

int fact1(int n){

int i, fact = 1;for (i = 1; i <= n; i++)

fact *= i;return (fact);

}

int fact2(int n){

unsigned int i, fact = 1;for (i = n; i != 0; i--)

fact *= i;return (fact);

}

표 5-2 증가 및 감소 루프에 대한 C 디스어셈블리

증가 루프 감소 루프

fact1 PROCMOV r2, r0MOV r0, #1CMP r2, #1MOV r1, r0BXLT lr

|L1.20|MUL r0, r1, r0ADD r1, r1, #1CMP r1, r2BLE |L1.20|BX lrENDP

fact2 PROCMOVS r1, r0MOV r0, #1BXEQ lr

|L1.12|MUL r0, r1, r0SUBS r1, r1, #1BNE |L1.12|BX lr

ENDP

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-5ID090708 Non-Confidential, Unrestricted Access

Page 104: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

루프 카운터를 필요한 이터레이션 수로 초기화하고 0까지 감소시키는 기술은 while 및 do 문에도 적용됩니다.

루프 언롤링

코드 크기가 커진다는 단점이 있지만 작은 루프는 성능을 향상시키기 위해 언롤링할 수 있습니다. 루프가 언롤링되면 루프 카운터를 자주 업데이트하지 않아도 되고 더 적은 수의 분기가 실행됩니다. 루프가 몇 번만 이터레이션되는 경우 루프 오버헤드가 완전히 사라지도록 완전히 언롤링할 수 있습니다. ARM 컴파일러는 -O3 -Otime에서 루프를 자동으로 언롤링합니다. 그렇지 않으면 소스 코드에서 모든 언롤링을 수행해야 합니다.

참고

루프의 수동 언롤링은 루프의 자동 재롤링과 컴파일러에 의한 다른 루프 최적화를 방해할 수 있습니다.

표 5-3에 나와 있는 두 개의 샘플 루틴을 사용하여 루프 언롤링의 장점과 단점을 보여 줄 수 있습니다. 두 루틴 모두 최하위 비트를 추출하고 계산하여 단일 비트를 효과적으로 테스트합니다. 그런 다음 이러한 비트는 시프트됩니다.

첫 번째 구현은 루프를 사용하여 비트를 계산합니다. 두 번째 루틴은 네 개의 n 시프트를 하나로 통합하여 적용된 최적화를 통해 시도된 처음 4번의 언롤링입니다. 언롤링을 자주 수행하면 최적화가 새로 수행됩니다.

표 5-3 롤링 및 언롤링된 비트 계산 루프에 대한 C 코드

비트 계산 루프 언롤링된 비트 계산 루프

int countbit1(unsigned int n){

int bits = 0;while (n != 0){

if (n & 1) bits++;n >>= 1;

}return bits;

}

int countbit2(unsigned int n){

int bits = 0;while (n != 0){

if (n & 1) bits++;if (n & 2) bits++;if (n & 4) bits++;if (n & 8) bits++;n >>= 4;

}return bits;

}

5-6 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 105: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

표 5-4에서는 5-6페이지의 표 5-3의 각 샘플 구현에 대해 컴파일러에서 생성된 기계어 코드의 디스어셈블리를 보여 줍니다. 여기서 이 두 가지 구현을 위한 C 코드는 -O2 옵션을 사용하여 컴파일되었습니다.

ARM7에서는 단일 비트 검사에 가장 왼쪽 열에 표시된 비트 계산 루프의 디스어셈블리에 있는 여섯 개의 주기가 사용됩니다. 코드 크기는 단 아홉 개의 명령어입니다. 비트 계산 루프의 언롤링된 버전은 비트당 평균 세 개의 주기만 사용하여 한 번에 네 개의 비트를 검사합니다. 그러나 그 결과로 코드 크기가 15개의 명령어로 커집니다.

5.1.5 휘발성 사용

높은 최적화 수준 -O2 및 -O3에서 코드를 컴파일할 때 종종 문제가 발생할 수 있습니다. 예를 들어 하드웨어를 폴링할 때 루프에 갇히거나 다중 스레드 코드가 이상하게 동작할 수도 있습니다. 이 경우 변수 중 일부를 volatile로 선언해야 할 수 있습니다.

변수를 volatile로 선언하면 컴파일러는 구현 외부에서 운영 체제나 하드웨어 등에 의해 언제든지 변수가 수정될 수 있다고 가정합니다. volatile로 정규화된 변수의 값은 언제든지 변경할 수 있기 때문에 변수의 실제 메모리 주소는 코드에서

표 5-4 롤링 및 언롤링된 비트 계산 루프에 대한 디스어셈블리

비트 계산 루프 언롤링된 비트 계산 루프

countbit1 PROCMOV r1, #0B |L1.20|

|L1.8|TST r0, #1ADDNE r1, r1, #1LSR r0, r0, #1

|L1.20|CMP r0, #0BNE |L1.8|MOV r0, r1BX lr

ENDP

countbit2 PROCMOV r1, r0MOV r0, #0B |L1.48|

|L1.12|TST r1, #1ADDNE r0, r0, #1TST r1, #2ADDNE r0, r0, #1TST r1, #4ADDNE r0, r0, #1TST r1, #8ADDNE r0, r0, #1LSR r1, r1, #4

|L1.48|CMP r1, #0BNE |L1.12|BX lr

ENDP

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-7ID090708 Non-Confidential, Unrestricted Access

Page 106: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

변수가 참조될 때마다 항상 액세스할 수 있어야 합니다. 즉, 메모리 액세스를 방지하기 위해 지역 레지스터에 캐시하는 등의 작업을 통해 컴파일러에서 변수 최적화를 수행할 수 없습니다.

반면에 변수가 volatile로 선언되지 않는 경우 컴파일러는 구현 외부에서 값을 수정할 수 없다고 가정할 수 있습니다. 따라서 컴파일러에서 변수 최적화를 수행할 수 있습니다.

표 5-5에서는 volatile 키워드를 사용하는 두 개의 샘플 루틴을 보여 줍니다. 이 두 루틴은 모두 상태 플래그 buffer_full이 true로 설정될 때까지 버퍼를 읽으며 buffer_full의 상태가 프로그램 흐름과 비동기식으로 변경될 수 있다고 가정합니다.

첫 번째 루틴은 루프의 원래 구현을 보여 줍니다. 변수 buffer_full은 이 구현에서 volatile로 정규화되지 않습니다. 반면에 두 번째 루틴은 buffer_full이 구현에서 volatile로 올바르게 정규화된 동일한 루프를 보여 줍니다.

표 5-5 비휘발성 및 휘발성 버퍼 루프에 대한 C 코드

버퍼 루프의 비휘발성 버전 버퍼 루프의 휘발성 버전

int buffer_full;int read_stream(void){

int count = 0;while (!buffer_full){

count++;}return count;

}

volatile int buffer_full;int read_stream(void){

int count = 0;while (!buffer_full){

count++;}return count;

}

5-8 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 107: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

표 5-6에서는 5-5페이지의 표 5-1의 각 샘플 구현에 대해 컴파일러에서 생성된 기계어 코드의 디스어셈블리를 보여 줍니다. 여기서 이 두 가지 구현을 위한 C 코드는 -O2 옵션을 사용하여 컴파일되었습니다.

표 5-6에 나와 있는 버퍼 루프의 비휘발성 버전 디스어셈블리에서, LDR r0, [r0, #0] 문은 buffer_full의 값을 |L1.8|이라는 루프 외부에서 r0 레지스터로 로드합니다. buffer_full은 volatile로 선언되지 않았기 때문에 컴파일러는 프로그램 외부에서 값을 수정할 수 없다고 가정합니다. buffer_full의 값을 r0으로 이미 읽어 들인 경우 값을 변경할 수 없기 때문에 컴파일러는 최적화를 사용할 수 있을 때 변수 재로딩을 생략합니다. 따라서 |L1.8|이라는 무한 루프가 발생합니다.

반면에 버퍼 루프의 휘발성 버전 디스어셈블리에서는 컴파일러가 buffer_full의 값이 프로그램 외부에서 변경될 수 있다고 가정하고 최적화를 수행하지 않습니다. 따라서 buffer_full의 값은 |L1.4|라는 루프 내부에서 레지스터 r0로 로드됩니다. 결과적으로 루프 |L1.4|는 어셈블리 코드에서 올바로 구현됩니다.

구현 외부에서 프로그램 상태 변경으로 인한 최적화 문제를 방지하려면 값이 구현에서 알 수 없는 방식으로 예기치 않게 변경될 때마다 변수를 volatile로 선언해야 합니다. 실제로 다음과 같은 경우에는 항상 변수를 volatile로 선언해야 합니다.

• 메모리 매핑된 주변 장치에 액세스할 경우

• 여러 개의 스레드 간에 전역 변수를 공유할 경우

• 인터럽트 루틴에 있는 전역 변수에 액세스할 경우

표 5-6 비휘발성 및 휘발성 버퍼 루프에 대한 디스어셈블리

버퍼 루프의 비휘발성 버전 버퍼 루프의 휘발성 버전

read_stream PROCLDR r1, |L1.28|MOV r0, #0LDR r1, [r1, #0]

|L1.12|CMP r1, #0ADDEQ r0, r0, #1BEQ |L1.12| ; infinite loopBX lrENDP

|L1.28|DCD ||.data||AREA ||.data||, DATA, ALIGN=2

buffer_fullDCD 0x00000000

read_stream PROCLDR r1, |L1.28|MOV r0, #0

|L1.8|LDR r2, [r1, #0]; ; buffer_fullCMP r2, #0ADDEQ r0, r0, #1BEQ |L1.8|BX lrENDP

|L1.28|DCD ||.data||AREA ||.data||, DATA, ALIGN=2buffer_full

DCD 0x00000000

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-9ID090708 Non-Confidential, Unrestricted Access

Page 108: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

5.2 코드 메트릭스

코드 메트릭스를 사용하면 코드 품질을 객관적인 방법으로 평가할 수 있습니다. ARM 컴파일러, 링커 및 Profiler는 간단한 코드 메트릭스를 생성하고 코드 품질을 향상시키기 위한 여러 가지 기능을 제공합니다. 특히 다음과 같은 기능을 제공합니다.

• 코드 및 데이터 크기 측정

• 정적 콜 그래프 생성

• 스택 사용 측정

• 객체 및 라이브러리에서 디버그 정보 줄이기

ARM Profiler에 대한 자세한 내용은 ARM Profiler 사용 설명서를 참조하십시오.

5.2.1 코드 및 데이터 크기 측정

다양한 옵션을 사용하여 응용 프로그램의 코드 및 데이터 크기를 측정할 수 있습니다. 다음을 참조하십시오.

• 컴파일러 참조 설명서의 2-77페이지의 --info=totals

• 유틸리티 설명서의 2-32페이지의 --info=topic[,topic,...]

• 링커 참조 설명서의 2-8페이지의 --[no_]callgraph

• 링커 참조 설명서의 2-41페이지의 --[no_]map

• 링커 참조 설명서의 2-62페이지의 --[no_]symbols

• 링커 참조 설명서의 2-69페이지의 --[no_]xref

5.2.2 스택 사용 측정

C와 C++ 모두 스택을 집중적으로 사용합니다. 예를 들어 스택은 다음을 보관하는 데 사용됩니다.

• 함수의 반환 주소

• AAPCS에 따라 보존해야 하는 레지스터

• 지역 배열, 구조체 및 C++ 클래스를 포함한 지역 변수

일반적으로 스택 사용을 자동으로 측정할 수는 없지만 수동으로 측정할 수는 있습니다. 이 작업은 다음과 같은 여러 가지 방법으로 수행할 수 있습니다.

• --callgraph와 링크하여 정적 콜 그래프를 생성합니다. 이렇게 하면 스택 사용을 포함한 모든 함수에 대한 정보가 표시됩니다.

5-10 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 109: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

• --info=stack 또는 --info=summarystack과 링크하여 모든 전역 기호의 스택 사용량을 나열합니다.

• 디버거를 사용하여 스택에서 사용할 수 있는 마지막 위치에 워치포인트를 설정하고 워치포인트가 올바로 설정되었는지 확인합니다.

• 디버거를 사용하여 다음을 수행합니다.

1. 필요한 것보다 훨씬 큰 스택 공간을 할당합니다.

2. 0 또는 0xDEADDEAD 같은 알려진 값으로 스택을 채웁니다.

3. 응용 프로그램 또는 응용 프로그램의 고정 부분을 실행합니다. 테스트 실행에서 가능한 한 많은 스택이 사용되도록 합니다. 예를 들어 가능한 한 많은 코드 분기를 실행하고 적절한 경우 인터럽트를 생성하여 스택 트레이스에 포함되도록 합니다.

4. 응용 프로그램의 실행이 완료된 후 메모리의 스택 영역을 검사하여 덮어쓴 알려진 값(0 또는 0xDEADDEAD)의 양을 확인합니다. 스택은 사용된 스택 부분에 있는 가비지와 나머지에 있는 0 또는 0xDEADDEAD 값을 보여 줍니다.

5. 알려진 항목의 수를 계산하고 8을 곱합니다. 이렇게 하면 메모리에서 스택이 얼마나 커졌는지 바이트 단위로 표시됩니다.

• RVISS의 경우 맵 파일을 사용하여 액세스가 허용되지 않는 메모리 영역을 정의합니다. 이 영역을 메모리에서 스택 바로 아래에 배치합니다. 스택이 금지된 영역으로 오버플로되면 디버거로 트래핑될 수 있는 데이터 중단이 발생합니다.

다음을 참조하십시오.

• 5-10페이지의 코드 및 데이터 크기 측정

• 링커 참조 설명서의 2-8페이지의 --[no_]callgraph

5.2.3 객체 및 라이브러리에서 디버그 정보 줄이기

종종 객체와 라이브러리에서 디버그 정보의 양을 줄이는 데 유용합니다. 디버그 정보의 수준을 낮추면 다음과 같은 효과가 있습니다.

• 객체 및 라이브러리의 크기가 줄어들어 이를 저장하는 데 필요한 디스크 공간의 양이 줄어듭니다.

• 링크 타임의 속도가 빨라집니다. 컴파일 주기에서 대부분의 링크 타임은 디버그 섹션을 모두 읽고 중복을 제거하는 데 소모됩니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-11ID090708 Non-Confidential, Unrestricted Access

Page 110: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

• 최종 이미지의 크기가 최소화됩니다. 그러면 디버거에서 디버그 기호를 로드하고 처리하는 시간이 빨라집니다.

소스 파일당 생성되는 디버그 정보의 양을 줄이는 방법에는 여러 가지가 있습니다. 예를 들면 다음과 같습니다.

• 헤더 파일에서 #define을 조건부로 사용하지 못하게 합니다. 이렇게 하면 링커가 중복되는 정보를 제거하기가 어려워집니다.

• 헤더 파일이 같은 순서로 #include되도록 C 또는 C++ 소스 파일을 수정합니다.

• 헤더 정보를 작은 블록으로 분할합니다. 즉, 크지만 적은 수의 헤더 파일보다는 작지만 많은 수의 헤더 파일을 사용합니다. 이렇게 하면 링커에서 보다 많은 공통 블록을 제거하는 데 도움이 됩니다.

• 실제로 필요한 경우에만 C 또는 C++ 소스 파일에 헤더 파일을 포함합니다.

• 동일한 헤더 파일이 여러 번 포함되지 않도록 합니다. 예를 들어 헤더 파일 foo.h가 있는 경우 다음을 추가합니다.

#ifndef foo_h#define foo_h...// rest of header file as before...#endif /* foo_h */

컴파일러 옵션 --remarks를 사용하여 보호되지 않은 헤더 파일에 대해 경고할 수 있습니다.

• --no_debug_macros 명령 행 옵션으로 코드를 컴파일하여 디버그 테이블에서 사전 처리기 매크로 정의를 제거합니다.

다음을 참조하십시오.

• 컴파일러 참조 설명서의 2-39페이지의 --debug_macros, --no_debug_macros

• 컴파일러 참조 설명서의 2-118페이지의 --remarks

5-12 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 111: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

5.3 함수

컴파일러에서 최적화를 보다 효율적으로 수행할 수 있도록 하려면 일반적으로 함수를 작고 간단하게 유지하는 것이 좋습니다. 이렇게 하는 방법에는 여러 가지가 있습니다. 예를 들면 다음과 같이 할 수 있습니다.

• 함수로 전달되거나 함수에서 반환되는 매개변수의 수를 최소화합니다.

• __value_in_regs를 사용하여 레지스터를 통해 함수에서 여러 값을 반환합니다.

• 가능한 경우 함수를 __pure로 정규화합니다.

5.3.1 매개변수 전달 오버헤드 최소화

함수로 매개변수를 전달하는 오버헤드를 최소화하는 방법에는 여러 가지가 있습니다. 예를 들면 다음과 같습니다.

• 각 인수가 한 단어 이하인 경우에는 함수가 네 개 이하의 인수를 사용하도록 합니다. C++에서 비정적 구성원 함수는 일반적으로 R0으로 전달되는 암시적 this 포인터 인수로 인해 세 개 이하의 인수를 가집니다.

• 스택된 인수를 전달하는 데 더 비중을 두도록 네 개 이상의 인수가 필요한 경우 함수에서 많은 양의 작업을 수행하도록 합니다.

• 관련 인수를 구조체에 놓고 함수가 호출될 때마다 포인터를 구조체에 전달합니다. 이렇게 하면 매개변수의 수가 줄어들고 가독성이 향상됩니다.

• 짝수 레지스터 인덱스에 정렬해야 하는 두 개의 인수 단어를 사용하므로 long long 매개변수의 수를 최소화합니다.

• 소프트웨어 부동 소수점이 사용되는 경우 double 매개변수의 수를 최소화합니다.

• 함수를 가변적인 개수의 매개변수와 함께 사용하지 않습니다. 가변적인 개수의 인수를 사용하는 함수는 스택의 모든 인수를 효과적으로 전달합니다.

5.3.2 __value_in_regs

C 및 C++에서 함수에서 여러 값을 반환하는 한 가지 방법은 구조체를 사용하는 것입니다. 일반적으로 구조체는 스택에서 반환되며 스택과 관련된 여러 가지 단점이 따릅니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-13ID090708 Non-Confidential, Unrestricted Access

Page 112: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

메모리 트래픽과 코드 크기를 줄이기 위해 레지스터를 통해 함수에서 여러 개의 값이 반환되도록 할 수 있습니다. 함수를 __value_in_regs로 정규화하여 struct에 있는 함수에서 최대 네 개의 단어를 반환할 수 있습니다. 예를 들어 다음과 같습니다.

typedef struct s_coord { int x; int y; } coord;coord reflect(int x1, int y1) __value_in_regs;

함수에서 여러 개의 값을 반환해야 하는 경우 위치에 관계없이 __value_in_regs를 사용할 수 있습니다. 예제에는 다음과 같은 작업이 포함됩니다.

• C 및 C++ 함수에서 여러 개의 값 반환

• 임베디드 어셈블리 언어 함수에서 여러 개의 값 반환

• 관리자 호출

• __user_initial_stackheap 재구현

__value_in_regs에 대한 자세한 내용은 컴파일러 참조 설명서에서 4-21페이지의 __value_in_regs를 참조하십시오.

5.3.3 __pure

순수 함수는 같은 인수로 호출하면 항상 같은 결과를 반환하는 함수입니다.

기본적으로 순수 함수에 대한 모든 특정 호출은 한 번만 평가하면 됩니다. 동일한 함수에 대한 호출 결과는 모두 동일하기 때문에 이후에 수행되는 코드의 함수에 대한 각 호출은 원래 호출의 결과로 대체될 수 있습니다.

함수가 순수 함수임을 컴파일러에 알리려면 함수를 __pure로 선언합니다.

5-15페이지의 표 5-7에서는 __pure 키워드를 사용하는 두 개의 샘플 루틴을 보여 줍니다. 루틴 둘 다 함수 fact를 호출하여 n!과 n!의 합을 계산합니다. fact 함수는 n!을 계산하는데 입력 인수 n에 따라서만 달라집니다. 따라서 fact는 순수 함수입니다.

5-14 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 113: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

첫 번째 루틴은 fact가 __pure로 선언되지 않는 fact 함수의 원래 구현을 보여 줍니다. 두 번째 구현에서는 컴파일러에 순수 함수임을 알리기 위해 fact 함수가 __pure로 정규화됩니다.

표 5-8에서는 표 5-7의 각 샘플 구현에 대해 컴파일러에서 생성된 기계어 코드의 디스어셈블리를 보여 줍니다. 여기서 이 두 가지 구현을 위한 C 코드는 -O2 옵션을 사용하여 컴파일되었습니다.

fact가 __pure로 정규화되지 않는 표 4-8의 함수 foo 디스어셈블리에서 컴파일러는 함수가 CSE를 위한 것임을 모르기 때문에 fact 함수는 두 번 호출됩니다. 반면에 fact가 __pure로 정규화되지 않는 표 4-8의 foo 디스어셈블리에서 컴파일러는 fact(n) + fact(n)를 추가할 때 CSE를 수행할 수 있기 때문에 fact는 두 번이 아니라 한 번만 호출됩니다.

표 5-7 순수 함수 및 순수하지 않은 함수에 대한 C 코드

__pure로 선언되지 않은 순수 함수 __pure로 선언된 순수 함수

int fact(int n){

int f = 1;while (n > 0)

f *= n--;return f;

} int foo(int n){

return fact(n)+fact(n);}

int fact(int n) __pure{

int f = 1;while (n > 0)

f *= n--;return f;

}int foo(int n){

return fact(n)+fact(n);}

표 5-8 순수 함수 및 순수하지 않은 함수에 대한 디스어셈블리

__pure로 선언되지 않은 순수 함수 __pure로 선언된 순수 함수

fact PROC...

foo PROCMOV r3, r0PUSH {lr}BL factMOV r2, r0MOV r0, r3BL factADD r0, r0, r2POP {pc}ENDP

fact PROC...

foo PROCPUSH {lr}BL factLSL r0,r0,#1POP {pc}ENDP

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-15ID090708 Non-Confidential, Unrestricted Access

Page 114: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

순수 함수에는 말 그대로 역효과가 있을 수 없습니다. 예를 들어 전역 상태에 액세스하면 같은 매개변수로 두 번 호출할 때마다 함수는 같은 값을 반환해야 한다는 규칙이 위반되기 때문에 순수 함수는 전역 변수를 사용하거나 포인터를 통해 지시하여 전역 상태를 쓰거나 읽을 수 없습니다. 따라서 프로그램에서 __pure를 사용할 때는 신중해야 합니다. 그러나 함수를 __pure로 선언할 수 없는 경우 컴파일러는 CSE와 같은 강력한 최적화를 수행할 수도 있습니다.

순수 함수에 대한 자세한 내용은 컴파일러 참조 설명서의 4-15페이지의 __pure를 참조하십시오.

5.3.4 ARM 함수 한정자 배치

많은 ARM 키워드 확장자는 함수의 동작 또는 호출 시퀀스를 수정합니다. 예를 들어 __pure, __irq, __swi, __swi_indirect, __softfp 및 __value_in_regs는 모두 이러한 방식으로 동작합니다.

이 함수 한정자는 모두 공통 구문을 가집니다. __pure와 같은 함수 한정자는 다음과 같은 위치에서 함수 선언을 정규화할 수 있습니다.

• 함수 선언 앞. 예를 들면 다음과 같습니다.

__pure int foo(int);

• 매개변수 목록에서 닫는 괄호 뒤. 예를 들면 다음과 같습니다.

int foo(int) __pure;

간단한 함수 선언의 경우 각 구문이 명확합니다. 그러나 반환 형식 또는 인수가 함수 포인터인 함수의 경우 접두사 구문이 부정확합니다. 예를 들어 다음 함수는 함수 포인터를 반환하지만 __pure가 함수 자체를 수정하는지 또는 반환된 포인터 형식을 수정하는지 여부는 명확하지 않습니다.

__pure int (*foo(int)) (int); /* declares 'foo' as a (pure?) function thatreturns a pointer to a (pure?) function.It is ambiguous which of the two functiontypes is pure. */

사실 foo 선언 앞에 있는 단일 __pure 키워드는 foo 자체와 foo가 반환한 함수 포인터 형식을 둘 다 수정합니다.

반면에 인수 및 반환 유형이 함수 포인터인 함수를 선언할 때 접미사 구문을 사용하면 __pure가 인수, 반환 유형 또는 기본 함수 중 어디에 적용되는지 알 수 있습니다. 예를 들면 다음과 같습니다.

5-16 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 115: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

int (*foo1(int) __pure) (int); /* foo1 is a pure function returninga pointer to a normal function */

int (*foo2(int)) (int) __pure; /* foo2 is a function returninga pointer to a pure function */

int (*foo3(int) __pure) (int) __pure; /* foo3 is a pure function returninga pointer to a pure function */

이 예제에서는 다음 사항이 적용됩니다.

• foo1 및 foo3은 자체적으로 수정됩니다.

• foo2 및 foo3은 수정된 함수로 포인터를 반환합니다.

• 함수 foo3 및 foo는 동일합니다.

접미사 구문은 접두사 구문보다 더 정확하기 때문에 ARM 함수 한정자로 함수를 한정할 때 가능한 한 접미사 구문을 활용하는 것이 좋습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-17ID090708 Non-Confidential, Unrestricted Access

Page 116: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

5.4 함수 인라인

함수 인라인은 코드 크기와 성능 사이에 트레이드 오프를 제공합니다. 기본적으로 컴파일러는 코드를 인라인할 것인지 여부를 자체적으로 결정합니다. 일반적으로 컴파일러는 최소 크기의 코드를 생성할 수 있도록 인라인에 대해 합리적인 결정을 내립니다. 임베디드 시스템에 대한 코드 크기가 가장 중요하기 때문입니다.

대부분의 경우 특정 함수를 인라인할 결정은 컴파일러에 남겨 두는 것이 좋습니다. 그러나 적절한 인라인 키워드를 사용하여 함수가 필요하다는 힌트를 컴파일러에 제공할 수 있습니다. 컴파일러는 또한 인라인과 관련하여 동작을 수정하기 위한 다양한 기능도 제공합니다. 이러한 기능을 사용할지 여부 또는 보다 일반적으로 함수를 인라인할지 여부를 결정할 때 고려해야 할 여러 가지 요소가 있습니다.

__inline, inline 또는 __forceinline으로 정규화되는 함수를 인라인 함수라고 합니다. C++에서는 클래스, 구조체 또는 공용체 내에서 정의되는 구성원 함수도 인라인 함수입니다.

참고

프로필 안내 방식 최적화는 함수 인라인에 영향을 줄 수 있습니다. 컴파일러 참조 설명서의 2-113페이지의 --profile=filename을 참조하십시오.

5.4.1 컴파일러의 인라인 결정 방식

인라인이 사용되면 컴파일러는 복잡한 결정 트리를 사용하여 함수가 언제 인라인되는지 결정합니다. 컴파일러는 함수가 인라인될지 여부를 결정하기 위해 다음과 같은 간단한 알고리즘을 사용합니다.

1. 함수가 __forceinline으로 정규화되면 함수가 인라인됩니다(가능한 경우).

2. 함수가 __inline으로 정규화되고 --forceinline 옵션이 선택되어 있으면 함수가 인라인됩니다(가능한 경우).

함수가 __inline으로 정규화되고 --forceinline 옵션이 선택되어 있지 않으면 함수가 인라인됩니다(적당한 경우).

3. 최적화 수준이 -O2 이상이거나 --autoinline이 선택되면 함수가 인라인됩니다(적당하고 가능한 경우).

5-18 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 117: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

함수를 인라인하는 것이 좋은지를 결정할 때 컴파일러는 -Ospace 또는 -Otime을 선택할지 여부를 포함하여 여러 개의 다른 기준을 고려합니다. -Otime을 선택하여 함수가 인라인될 가능성을 높입니다. 자세한 내용은 컴파일러에서 인라인하기 적당한 경우을 참조하십시오.

언제 함수를 인라인하는 것이 좋은지에 대해 컴파일러가 내린 결정은 재정의할 수 없습니다. 예를 들어 컴파일러가 적당하지 않다고 결정한 경우에는 함수를 인라인할 수 없습니다.

5.4.2 컴파일러에서 인라인하기 적당한 경우

컴파일러는 다음을 포함하여 많은 조건에 따라 언제 함수를 인라인하는 것이 좋은지를 자체적으로 결정합니다.

• 함수의 크기 및 함수가 호출되는 횟수

• 현재 최적화 수준

• 속도(-Otime)가 최적화 대상인지 아니면 크기(-Ospace)가 최적화 대상인지 여부

• 함수에 외부 또는 정적 연결 중 어느 것이 있는지 여부

• 함수에 포함된 매개변수의 수

• 함수 반환 값 사용 여부

궁극적으로 컴파일러는 함수가 __forceinline으로 정규화되더라도 함수를 인라인하지 않을 수 있습니다. 일반적인 규칙은 다음과 같습니다.

• 작은 함수일수록 인라인될 가능성이 더 높습니다.

• -Otime으로 컴파일된 함수는 인라인될 가능성이 높습니다.

• 코드 밀도와 성능에 악영향을 줄 수 있으므로 큰 함수는 일반적으로 인라인되지 않습니다.

5.4.3 인라인 관리

컴파일러에서 __forceinline 키워드를 사용하여 함수를 강제로 인라인할 수 있습니다. 문제가 발생하지 않는 한 컴파일러는 함수를 인라인으로 배치합니다. 예를 들어 재귀 함수는 자체로 한 번만 인라인됩니다. 컴파일러에서 __inline으로 표시된 모든 함수를 강제로 인라인하려면 코드를 --forceinline 명령 행 옵션으로 컴파일하십시오.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-19ID090708 Non-Confidential, Unrestricted Access

Page 118: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

최상위 수준의 최적화(-O2 및 -O3)에서 컴파일러는 사용자의 명시적인 힌트 없이도 인라인을 설정해야 하는 함수에 자동으로 인라인을 설정합니다. 자세한 내용은 5-24페이지의 함수를 정적으로 표시를 참조하십시오.

--no_autoinline 및 --autoinline 명령 행 옵션을 사용하여 가장 높은 최적화 수준에서 함수의 자동 인라인을 제어할 수 있습니다. 일반적으로 자동 인라인이 활성화되면 컴파일러는 인라인해도 되는 것을 모두 인라인합니다. 자동 인라인이 비활성화되면 __inline으로 표시된 함수만 인라인 대상이 됩니다.

--no_inline 및 --inline 키워드를 사용하여 인라인의 수행 여부를 제어할 수 있습니다. 기본적으로 함수의 인라인은 활성화됩니다. --no_inline 명령 행 옵션을 사용하여 함수의 인라인을 비활성화하면 컴파일러는 명시적으로 __forceinline으로 정규화된 함수만 인라인하려고 시도합니다.

다음을 참조하십시오.

• 컴파일러 참조 설명서의 2-18페이지의 --autoinline, --no_autoinline

• 컴파일러 참조 설명서의 2-61페이지의 --forceinline

• 컴파일러 참조 설명서의 2-78페이지의 --inline, --no_inline

• 컴파일러 참조 설명서의 4-7페이지의 __forceinline

• 컴파일러 참조 설명서의 4-10페이지의 __inline

5.4.4 자동 인라인

-O2 및 -O3 최적화 수준에서 컴파일러는 정의되어 있지만 인라인 함수가 아닌 함수에 대한 호출을 인라인할 것인지 고려합니다. 이는 정적 함수에 대해 가장 효율적인데, 모든 정적 함수 사용은 인라인할 수 있으며 라인 외부 복사를 수행하지 않아도 되기 때문입니다. 인라인이 아닌 모든 함수는 함수가 정의된 변환 단위 외부에서 사용되지 않으면 정적으로 표시하는 것이 가장 좋습니다. 변환 단위는 #include 지시어를 사용한 결과로 포함되는 모든 헤더 및 소스 파일과 함께 사전 처리되는 소스 파일 출력입니다. 일반적으로는 헤더 파일에 인라인이 아닌 함수의 정의를 배치하지 않습니다.

-O3 수준에서 기본적으로 사용되는 --multifile 옵션 또는 --ltcg를 사용하여 컴파일하는 경우에는 컴파일러가 다른 변환 단위에서 정의되는 함수 호출에 대해 자동 인라인을 수행할 수 있습니다.

--multifile의 경우 두 변환 단위는 모두 동일한 컴파일러 호출에서 컴파일해야 합니다. --ltcg의 경우에는 두 변환 단위를 링크만 하면 됩니다.

--no_inline은 자동 인라인을 비활성화합니다.

5-20 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 119: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

5.4.5 C++, C90, C99 및 GNU C90 컴파일러 모드 간의 동작 차이

컴파일러가 컴파일하는 언어에 따라 일부 영역에서는 인라인 효과가 달라집니다.

__forceinline은 컴파일러가 인라인을 보다 많이 시도한다는 점을 제외하면 __inline과 같이 동작합니다.

C++ 및 C90 모드

C90에서는 inline 키워드를 사용할 수 없습니다.

C90에서 __inline의 효과와 C++에서 __inline 및 inline의 효과는 같습니다.

extern 함수를 인라인으로 선언할 때는 해당 함수가 사용되는 모든 변환 단위에서 함수를 정의해야 하며 각 변환 단위에서 같은 정의를 사용해야 합니다.

모든 변환 단위에서 함수를 정의해야 하는 요구 사항은 함수에 외부 연결이 있는 경우에도 적용됩니다.

인라인 함수를 여러 파일에서 사용하는 경우에는 보통 헤더 파일에 함수 정의를 배치합니다.

인라인이 아닌 함수 정의를 헤더 파일에 배치하면 각 변환 단위마다 별도의 함수가 만들어질 수 있기 때문에 권장되지 않습니다. 인라인이 아닌 함수가 extern 함수인 경우에는 링크 타임에 기호가 중복될 수 있습니다. 인라인이 아닌 함수가 static인 경우에는 코드가 불필요하게 중복될 수 있습니다.

C++ 구조체, 클래스 또는 공용체 선언 내에서 정의되는 구성원 함수는 암시적으로 인라인됩니다. 이러한 함수는 inline 또는 __inline 키워드로 선언되는 것처럼 취급됩니다.

명시적으로 static으로 선언되는 경우가 아니면 인라인 함수에는 extern 연결이 있습니다. 인라인 함수를 정적으로 선언하는 경우 함수의 라인 외부 복사본이 해당 변환 단위에 대해 고유해야 하므로, 인라인 함수를 정적으로 선언하면 코드가 불필요하게 중복될 수 있습니다.

컴파일러는 함수를 인라인할 수 없을 때와 인라인하지 않도록 결정할 때 함수의 라인 외부 복사본에 대한 일반 호출을 생성합니다.

함수가 사용되는 모든 변환 단위에 함수를 정의해야 하는 요구 사항은 컴파일러가 모든 extern 인라인 함수의 라인 외부 복사본을 내보내도 되지 않음을 의미합니다. 컴파일러는 extern 인라인 함수의 라인 외부 복사본을 내보낼 때 공통 그룹

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-21ID090708 Non-Confidential, Unrestricted Access

Page 120: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

을 사용하여 링커가 중복되는 항목을 제거하고 서로 다른 객체의 동일한 라인 외부 함수에 최대 하나의 복사본만 보관되도록 합니다. 링커 사용 설명서의 3-11페이지의 공통 그룹 또는 섹션 제거를 참조하십시오.

C99 모드

외부 연결이 포함된 C99 인라인 함수에 대한 규칙은 C++에 대한 규칙과는 다릅니다. C99는 인라인 정의와 외부 정의를 구분합니다. 인라인 함수가 정의되어 있는 지정된 변환 단위 내에서 인라인 함수가 항상 inline으로 선언되며 extern으로는 선언되지 않으면 해당 정의는 인라인 정의입니다. 그렇지 않은 경우 해당 정의는 외부 정의입니다. 이러한 인라인 정의는 --no_inline을 사용할 때도 라인 외부 복사본을 생성하는 데 사용되지 않습니다.

각 인라인 함수 사용은 동일한 변환 단위의 정의(인라인 정의 또는 외부 정의일 수 있음)를 통해 인라인될 수도 있고 외부 정의에 대한 호출이 될 수도 있습니다. 인라인 함수를 사용하는 경우에는 일부 변환 단위에 정확히 하나의 외부 정의가 있어야 합니다. 이는 외부 함수 사용 시 적용되는 규칙과 같습니다. 실제로 모든 인라인 함수 사용이 인라인되는 경우 외부 정의가 없어도 오류가 발생하지 않습니다. --no_inline을 사용하는 경우에는 외부 정의만 사용됩니다.

일반적으로는 extern이 아닌 inline을 사용하여 외부 연결이 포함된 인라인 함수를 헤더 파일에 인라인 함수로 배치합니다. 또한 소스 파일에도 외부 정의가 있습니다. 예를 들면 다음과 같습니다.

예제 5-1 C99에서 함수 인라인

/* example_header.h */inline int my_function (int i){

return i + 42; // inline definition}

/* file1.c */#include “example_header.h”

... // uses of my_function()

/* file2.c */#include “example_header.h”

... // uses of my_function()

/* myfile.c */

5-22 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 121: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

#include “example_header.h”extern inline int my_function(int); // causes external definition.

이는 C++에서 일반적으로 사용되는 방식과 같지만, C++에서는 특수한 외부 정의와 정의에 대한 요구 사항이 없습니다.

인라인 함수 정의는 변환 단위마다 서로 다를 수 있습니다. 그러나 5-22페이지의 C99에서 함수 인라인과 같은 실제 사용에서는 정의가 모두 동일합니다.

--multifile 또는 --ltcg로 인라인하는 경우, 한 변환 단위의 호출이 다른 변환 단위의 외부 정의를 사용하여 인라인될 수 있습니다.

C99에서는 인라인 정의에 대해 몇 가지 제한이 적용됩니다. 즉, 수정 가능한 지역 정적 객체는 정의할 수 없으며 정적 연결이 포함된 식별자는 참조할 수 없습니다.

다른 모든 모드와 마찬가지로 C90 모드에서도 __inline 및 inline의 효과는 같습니다.

정적 연결이 포함된 인라인 함수의 동작은 C99와 C++에서 동일합니다.

GNU C90 모드

인라인에 대한 GNU C90 규칙은 다른 컴파일러 모드의 규칙과 다릅니다. http://gcc.gnu.org에서 GNU 설명서를 참조하십시오.

5.4.6 링커 인라인

링커는 매우 짧은 일부 함수에 대한 호출을 함수 본문으로 교체할 수 있습니다. 링커 참조 설명서의 2-31페이지의 --[no_]inline을 참조하십시오.

5.4.7 데이터와 --no_inline 및 --inline 명령 행 옵션 디버그

일반적으로는 인라인 함수 사용에 대해 생성되는 디버그 보기를 효율적으로 사용할 수 있습니다. 그러나 디버깅을 인라인하지 않는 것이 보다 명확하므로 인라인 함수를 사용하지 않는 것이 더 좋은 경우도 있습니다. --no_inline 및 --inline 명령 행 옵션을 사용하면 함수 인라인을 활성화 및 비활성화할 수 있습니다. 컴파일러 참조 설명서의 2-78페이지의 --inline, --no_inline를 참조하십시오.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-23ID090708 Non-Confidential, Unrestricted Access

Page 122: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

5.4.8 함수를 정적으로 표시

최적화 수준 -O2 및 -O3에서 함수가 __inline 또는 inline으로 선언되지 않더라도 컴파일러는 인라인하는 것이 적당한 경우 함수를 자동으로 인라인할 수 있습니다.

참고

높은 최적화 수준에서 함수의 자동 인라인을 제어하려면 --no_autoinline 및 --autoinline 명령 행 옵션을 사용하십시오.

함수가 명시적으로 static(또는 __inline)으로 선언되지 않더라도 컴파일러는 다른 모듈로부터 호출되는 경우에 대비해 객체 파일에 라인 외부 버전을 유지해야 합니다. 다음 방법 중 하나를 사용하여 사용되지 않는 라인 외부 함수를 자체 섹션에 배치하지 않는 이상 링커는 사용되지 않는 라인 외부 함수를 객체에서 제거할 수 없습니다.

• 컴파일러 참조 설명서의 2-125페이지의 --split_sections

• 컴파일러 참조 설명서의 4-52페이지의 __attribute__((section("name")))

• 컴파일러 참조 설명서의 4-59페이지의 #pragma arm section [section_sort_list]

• 링커 피드백

모듈 외부에서 호출되지 않은 함수를 static으로 선언하지 않으면 사용자의 코드에 악영향을 줄 수 있습니다. 예를 들면 다음과 같습니다.

• 이미지에 라인 외부 버전의 함수가 유지되므로 코드 크기가 더 커집니다.

함수가 자동으로 인라인되면 함수가 static으로 선언되지 않는 한 함수의 인라인 버전 및 라인 외부 버전이 둘 다 최종 이미지에 있게 됩니다. 따라서 코드 크기가 커질 수 있습니다.

• 표시할 함수의 인라인 버전과 라인 외부 버전이 둘 다 있기 때문에 디버그 뷰가 복잡해 집니다.

디버그 뷰에 브레이크포인트 또는 단일 단계별 실행을 설정할 때 코드에 함수의 인라인과 라인 외부 복사본을 유지하는 것은 경우에 따라 복잡할 수 있습니다. 인라인 또는 라인 외부 버전을 통해 단계별로 실행할 때 무슨 일이 발생했는지 알 수 있도록 디버거는 인터리브된 소스 뷰에 인라인과 라인 외부 버전을 표시해야 합니다.

5-24 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 123: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

이 문제로 인해 다른 모듈에서 호출할 수 없는 경우 인라인이 아닌 함수를 static으로 선언해야 합니다.

5.4.9 ROM 이미지에서 인라인 함수에 브레이크포인트 설정

인라인 함수에서 브레이크포인트를 설정하면 RealView 디버거가 해당 함수의 인라인된 각 인스턴스에 브레이크포인트를 설정하려고 시도합니다. RealView ICE를 사용하여 이미지를 ROM에서 디버그하고 인라인 인스턴스의 수가 사용 가능한 하드웨어 브레이크포인트의 수보다 큰 경우 디버거는 추가 브레이크포인트를 설정할 수 없습니다. 이 경우 디버거는 오류를 보고합니다.

다음을 참조하십시오.

• 컴파일러 참조 설명서의 2-18페이지의 --autoinline, --no_autoinline

• 컴파일러 참조 설명서의 2-61페이지의 --forceinline

• 컴파일러 참조 설명서의 2-78페이지의 --inline, --no_inline

• 컴파일러 참조 설명서의 4-7페이지의 __forceinline

• 컴파일러 참조 설명서의 4-10페이지의 __inline

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-25ID090708 Non-Confidential, Unrestricted Access

Page 124: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

5.5 데이터 정렬

여러 C 데이터 형식을 특정 바이트 단위로 정렬하면 저장성이 극대화될 뿐 아니라 ARM 명령어 세트를 통해 신속하고 효율적으로 메모리에 액세스할 수 있습니다. 예를 들어 객체가 저장된 주소가 4의 배수일 때 즉, 4바이트 단위로 4바이트 객체가 저장될 때 ARM 아키텍처에서는 하나의 명령어만 사용하여 4바이트 변수에 액세스할 수 있습니다.

컴파일러에서 데이터 객체를 저장하는 기본 방식이 표 5-9에 나와 있습니다.

데이터 정렬은 컴파일러에서 변수를 실제 메모리 주소에 배치할 때 관여합니다. 예를 들어 다음 구조의 bmem와 cmem 사이에는 3바이트 간격이 필요합니다.

struct example_st {int amem;char bmem;int cmem;

};

ARM과 Thumb 프로세서는 기본 방식으로 정렬된 데이터, 즉 4의 배수인 주소에 있는 더블워드와 워드, 2의 배수인 주소에 있는 하프워드 및 모든 바이트 주소에 있는 단일 바이트에 효과적으로 액세스하도록 설계되었습니다. 이러한 데이터는 해당 기본 크기 경계에 있습니다.

표 5-9 바이트 정렬별 데이터 객체의 컴파일러 스토리지

형식 바이트 정렬

char 1 모든 바이트 주소에 위치함

short 2 2의 배수인 주소에 위치함

float, int, long, pointer

4 4의 배수인 주소에 위치함

long longdouble

8 4의 배수인 주소에 위치함

5-26 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 125: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

5.5.1 데이터 정렬 유형

메모리의 데이터에 대한 모든 액세스는 다음과 같은 범주로 분류할 수 있습니다.

• 예를 들어 0x1000에서 워드 경계의 기본 정렬. ARM 컴파일러는 일반적으로 LDR 및 STR 명령어를 사용하여 이러한 항목이 효율적으로 액세스되도록 변수와 패드 구조체를 정렬합니다.

• 알려진 그러나 기본이 아닌 정렬, 예를 들어 주소 0x1001에 있는 워드. 이러한 유형의 정렬은 일반적으로 불필요한 패딩을 제거하기 위해 구조체가 패킹될 때 발생합니다. C 및 C++에서 __packed 한정자 또는 #pragma pack(n) pragma는 구조체가 패킹되었다는 것을 나타내기 위해 사용됩니다.

• 알 수 있는 정렬, 예를 들어 임의 주소에 있는 워드. 이러한 유형의 정렬은 일반적으로 임의의 주소에 있는 워드를 가리킬 수 있는 포인터를 정의할 때 발생합니다. C 및 C++에서 __packed 한정자 또는 #pragma pack(n) pragma는 포인터가 기본 정렬 경계에 있지 않는 워드에 액세스할 수 있음을 나타내기 위해 사용됩니다.

__packed 한정자, 패킹된 구조체 및 정렬되지 않은 포인터에 대한 자세한 내용은 5-28페이지의 __packed 한정자 및 정렬되지 않은 액세스를 참조하십시오.

#pragma pack(n)에 대한 자세한 내용은 컴파일러 참조 설명서에서 4-69페이지의 #pragma pack(n)을 참조하십시오.

5.5.2 정렬되지 않은 데이터 액세스

예를 들어 메모리의 정렬되지 않은 데이터에 직접 액세스하기 위해 명령어를 사용할 수 있는 CISE 아키텍처로부터 레거시 코드를 이식할 때, 메모리의 정렬되지 않은 데이터에 액세스해야 할 수도 있습니다.

ARMv4 및 ARMv5 아키텍처와 ARMv6 아키텍처(구성 방식에 따라 다름)에서는 메모리의 정렬되지 않은 데이터에 액세스할 때 주의해야 합니다. 그렇지 않으면 예상치 못한 결과가 반환됩니다. 예를 들어 C 또는 C++ 소스 코드에 워드를 읽기 위해 기존의 포인터가 사용될 때 ARM 컴파일러는 LDR 명령어를 사용하여 워드를 읽는 어셈블리 언어 코드를 생성합니다. 이 명령어는 주소가 4의 배수일 때, 예를 들어 워드 경계에 있을 때 정상적으로 실행됩니다. 그러나 주소가 4의 배수가 아니면 LDR은 정렬되지 않은 워드를 실제로 로드하지 않고 회전된 결과를 반환합니다. 일반적으로 이 회전은 프로그래머가 예상했던 결과가 아닙니다.

ARMv6 이상 아키텍처에서는 정렬되지 않은 액세스가 완전히 지원됩니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-27ID090708 Non-Confidential, Unrestricted Access

Page 126: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

5.5.3 __packed 한정자 및 정렬되지 않은 액세스

__packed 한정자는 유효한 유형의 정렬을 하나로 설정합니다. 패킹된 유형의 객체는 정렬되지 않은 액세스를 통해 읽거나 쓰여집니다.

패킹할 수 있는 객체에는 다음과 같은 것들이 있습니다.

• 구조체

• 공용체

• 포인터

__packed 한정자에 대한 자세한 내용은 컴파일러 참조 설명서에서 4-12페이지의 __packed를 참조하십시오.

구조체의 정렬되지 않은 필드

효율성을 위해 구조체의 필드는 해당 기본 크기 경계에 있습니다. 따라서 컴파일러에서 필드 사이에 패딩을 삽입하여 필드를 정렬해야 하는 경우가 있습니다.

공간이 부족한 경우 __packed 한정자를 사용하여 필드 사이에서 패딩하지 않고 구조체를 생성할 수 있습니다. 구조체는 다음 두 가지 방식으로 패킹할 수 있습니다.

• 전체 struct는 __packed로 선언할 수 있습니다. 예를 들면 다음과 같습니다.

__packed struct mystruct{

char c;short s;

} // not recommended

구조체의 각 필드는 __packed 한정자를 상속합니다.

전체 struct를 __packed로 선언하면 일반적으로 코드 크기가 커지고 성능이 저하됩니다. 자세한 내용은 5-30페이지의 __packed 구조체 및 개별 __packed 필드를 참조하십시오.

• struct 내의 정렬되지 않은 개별 필드는 __packed로 선언할 수 있습니다. 예를 들면 다음과 같습니다.

struct mystruct{

char c;__packed short s; // recommended

}

이 방법은 구조체 패킹에 권장됩니다. 자세한 내용은 5-30페이지의 __packed 구조체 및 개별 __packed 필드를 참조하십시오.

5-28 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 127: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

참고

공용체에도 이와 같은 방법을 사용할 수 있습니다. 전체 공용체를 __packed로 선언하거나 __packed 속성을 사용하여 메모리에 정렬되지 않은 공용체의 구성요소를 확인합니다.

__packed로 정규화된 구조체에서 읽고 해당 구조체에 쓰려면 정렬되지 않은 액세스가 필요하며, 이에 따라 성능이 저하될 수 있습니다. 자세한 내용은 5-30페이지의 __packed 구조체 및 개별 __packed 필드를 참조하십시오.

정렬되지 않은 포인터

기본적으로 ARM 컴파일러에서는 기존의 C 포인터가 메모리 내의 정렬된 워드를 가리키는 것으로 가정하는 데, 이를 통해 컴파일러는 더 효율적인 코드를 생성할 수 있습니다.

임의의 주소에 있는 워드를 가리킬 수 있는 포인터를 정의하려면 포인터를 정의할 때 __packed 한정자를 사용하여 포인터를 지정해야 합니다. 예를 들면 다음과 같습니다.

__packed int *pi; // pointer to unaligned int

포인터가 __packed로 선언되는 경우 ARM 컴파일러에서는 정렬에 관계없이 포인터의 참조되지 않은 값에 올바르게 액세스하는 코드를 생성합니다. 생성된 코드는 간단한 LDR 명령어가 아니라 일련의 바이트 액세스 또는 변수 정렬 방식에 따른 시프트 및 마스킹 명령어로 구성됩니다. 결과적으로 포인터를 __packed로 선언하면 코드 크기가 커지고 성능이 저하됩니다.

하프워드에 액세스하기 위한 정렬되지 않은 LDR 명령어

경우에 따라 컴파일러에서 정렬되지 않은 LDR 명령어를 의도적으로 생성할 수도 있습니다. 특히 아키텍처가 전용 하프워드 로드 명령어를 지원하는 경우에도 컴파일러는 이와 같은 방법으로 메모리에서 하프워드를 로드할 수 있습니다.

예를 들어 __packed 구조체 내의 정렬되지 않은 short에 액세스하려면 컴파일러는 필요한 하프워드를 레지스터의 상위 하프에 로드한 다음 하위 하프로 시프트할 수 있습니다. 이 작업은 한 번의 메모리 액세스가 필요한 반면 LDRB 명령어를 사용하여 같은 작업을 수행하려면 두 번의 메모리 액세스와 2바이트를 병합하기 위한 명령어가 필요합니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-29ID090708 Non-Confidential, Unrestricted Access

Page 128: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

5.5.4 __packed 구조체 및 개별 __packed 필드

패킹된 struct를 최적화할 때 컴파일러는 각 필드의 정렬을 추론하여 액세스를 개선하려고 시도합니다. 그러나 컴파일러가 항상 __packed struct에 각 필드의 정렬을 추론할 수 있는 것은 아닙니다. 반면에 구조체의 개별 필드가 __packed로 정의되면 struct 내의 기본 방식으로 정렬된 구성원에 대한 빠른 액세스가 보장됩니다. 따라서 패킹된 구조체를 사용해야 하는 경우 전체 구조 자체보다는 항상 구조체의 개별 필드를 패킹하는 것이 좋습니다.

참고

struct의 정렬되지 않은 개별 필드를 __packed로 선언하면 정렬되지 않은 struct 필드를 프로그래머에게 확실히 알리는 장점도 있습니다.

struct를 패킹하지 않는 것, 전체 struct를 패킹하는 것 및 struct의 개별 필드를 패킹하는 것의 차이는 표 5-10에 나와 있는 struct의 세 가지 구현을 보면 알 수 있습니다.

첫 번째 구현에서는 struct가 패킹되지 않습니다. 두 번째 구현에서는 전체 구조체 mystruct가 __packed로 정규화되지 않습니다. 세 번째 구현에서는 __packed 특성이 mystruct 구조체에서 제거되며 정렬되지 않은 개별 필드가 __packed로 선언되지 않습니다.

5-31페이지의 표 5-11에서는 표 5-10의 각 샘플 구현에 대해 컴파일러에서 생성된 기계어 코드의 디스어셈블리를 보여 줍니다. 여기서 이 두 가지 구현을 위한 C 코드는 -O2 옵션을 사용하여 컴파일되었습니다.

표 5-10 패킹되지 않은 구조체, 패킹된 구조체 및 개별적으로 패킹된 필드가 있는 구조체

에 대한 C 코드

패킹되지 않은 구조체 __packed struct __packed fields

struct foo{

char one;short two;char three;int four;

} c;

__packed struct foo{

char one;short two;char three;int four;

} c;

struct foo{

char one;__packed short two;char three;int four;

} c;

5-30 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 129: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

참고

-Ospace 및 -Otime 컴파일러 옵션은 정렬되지 않은 요소에 대한 액세스가 인라인으로 이루어지는지 또는 함수 호출을 통해 이루어지는지를 제어합니다. -Otime을 사용하면 정렬되지 않은 인라인 액세스가 발생하는 반면 -Ospace를 사용하면 함수 호출을 통해 이루어진 비정렬 액세스가 발생합니다.

표 5-11에 나와 있는 패킹되지 않은 struct의 디스어셈블리에서 컴파일러는 항상 정렬된 워드 또는 하프워드 주소에 있는 데이터에 액세스합니다. struct가 패딩되어 struct의 모든 구성원이 기본 크기 경계에 있기 때문에 컴파일러는 이 작업을 수행할 수 있습니다.

표 5-11의 __packed struct의 디스어셈블리에서, 필드 one 및 three는 기본적으로 기본 크기 경계에 정렬되며 따라서 컴파일러는 정렬된 액세스를 수행합니다. 컴파일러는 정렬된 것으로 확인한 필드에 대해 정렬된 워드 또는 하프워드 액세스를 항상 수행합니다. 정렬되지 않은 필드 two의 경우 컴파일러는 여러 개의 정렬된 메모리 액세스(LDR/STR/LDM/STM)와 고정된 시프트 및 마스킹을 함께 사용하여 메모리의 올바른 바이트에 액세스합니다. 필드가 기본 크기 경계에 있는지 결정할 수 없기 때문에 컴파일러는 필드 four에 액세스하기 위해 알 수 없는 정렬에서 부호 없는 워드를 읽기 위해 AEABI 런타임 루틴 __aeabi_uread4를 호출합니다.

표 5-11 패킹되지 않은 구조체, 패킹된 구조체 및 개별적으로 패킹된 필드가 있는 구조체

에 대한 디스어셈블리

패킹되지 않은 구조체 __packed struct __packed fields

; r0 contains address of c; char oneLDRB r1, [r0, #0]; short twoLDRSH r2, [r0, #2]; char threeLDRB r3, [r0, #4]; int fourLDR r12, [r0, #8]

; r0 contains address of c; char oneLDRB r1, [r0, #0]; short twoLDRB r2, [r0, #1]LDRSB r12, [r0, #2]ORR r2, r12, r2, LSL #8; char threeLDRB r3, [r0, #3]; int fourADD r0, r0, #4BL __aeabi_uread4

; r0 contains address of c; char oneLDRB r1, [r0, #0]; short twoLDRB r2, [r0, #1]LDRSB r12, [r0, #2]ORR r2, r12, r2, LSL #8; char threeLDRB r3, [r0, #3]; int fourLDR r12, [r0, #4]

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-31ID090708 Non-Confidential, Unrestricted Access

Page 130: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

5-31페이지의 표 5-11의 개별적으로 패킹된 필드와 함께 struct의 디스어셈블리에서 one, two 및 three는 전체 struct가 __packed로 정규화된 경우와 동일한 방식으로 액세스됩니다. 구조체 내에 __packed short가 있으면 컴파일러에서 four 필드가 기본 크기 경계에 있는지 확인하기 쉬워지므로 전체 struct가 패킹되는 상황과는 반대로 컴파일러는 four 필드에 대한 워드로 정렬된 액세스를 수행합니다.

5-32 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 131: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

5.6 부동 소수점 산술 사용

ARM 컴파일러는 소프트웨어와 하드웨어에서 부동 소수점 산술을 관리하기 위한 많은 기능을 제공합니다. 예를 들어 부동 소수점을 위한 소프트웨어 또는 하드웨어 지원, 특정한 하드웨어 아키텍처와 IEEE 부동 소수점 표준 준수 수준을 지정할 수 있습니다.

부동 소수점 옵션의 선택은 부동 소수점 성능, 시스템 비용 및 시스템 유연성 간의 다양한 트레이드 오프를 결정합니다. 성능, 비용 및 유연성 간에 최상의 트레이드 오프를 확보하려면 부동 소수점 옵션을 올바로 선택해야 합니다.

5.6.1 부동 소수점 연산 지원

ARM 프로세서 코어에는 부동 소수점 하드웨어가 포함되지 않습니다. 부동 소수점 산술은 다음 경우 별도로 지원해야 합니다.

• 소프트웨어에서 부동 소수점 라이브러리 fplib를 통해. 라이브러리는 추가 하드웨어를 사용하지 않고 부동 소수점 연산을 구현하기 위해 호출할 수 있는 기능을 제공합니다. 라이브러리 설명서의 4-2페이지의 소프트웨어 부동 소수점 라이브러리 fplib를 참조하십시오.

• 하드웨어에서, ARM 프로세서 코어에 포함된 하드웨어 VFP 보조 프로세서를 사용하여 필요한 부동 소수점 연산 제공. VFP는 IEEE 부동 소수점을 구현하고 단정밀도 및 배정밀도(확장 정밀도는 아님)를 지원하는 보조 프로세서 아키텍처입니다.

참고

실제로 VFP의 부동 소수점 산술은 일반적인 경우를 실행하는 하드웨어와 예외적인 경우를 처리하고 예외를 발생시키는 소프트웨어의 조합을 사용하여 구현됩니다. 자세한 내용은 5-36페이지의 VFP 지원을 참조하십시오.

부동 소수점 산술을 위한 소프트웨어와 하드웨어 지원 사이의 차이는 C로 부동 소수점 산술 작업을 구현하는 함수를 보여 주는 예제 5-2를 보면 알 수 있습니다.

예제 5-2 부동 소수점 연산

float foo(float num1, float num2){

float temp, temp2;temp = num1 + num2;

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-33ID090708 Non-Confidential, Unrestricted Access

Page 132: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

temp2 = num2 * num2;return temp2-temp;

}

5-33페이지의 예제 5-2의 C 코드가 명령 행 옵션 --cpu 5TE --fpu softvfp로 컴파일되면 컴파일러는 예제 5-3의 디스어셈블리와 함께 기계어 코드를 생성합니다. 이 예에서 부동 소수점 산술은 __aeabi_fmul과 같은 라이브러리 루틴에 대한 호출을 통해 소프트웨어에서 수행됩니다.

예제 5-3 소프트웨어에서 부동 소수점 연산 지원

||foo|| PROCPUSH {r4-r6, lr}MOV r4, r1BL __aeabi_faddMOV r5, r0MOV r1, r4MOV r0, r4BL __aeabi_fmulMOV r1, r5POP {r4-r6, lr}B __aeabi_fsubENDP

5-33페이지의 예제 5-2의 C 코드가 명령 행 옵션 --fpu vfp로 컴파일되면 컴파일러는 예제 5-4의 디스어셈블리와 함께 기계어 코드를 생성합니다. 이 예에서 부동 소수점 산술은 VMUL.F32와 같은 부동 소수점 산술을 통해 하드웨어에서 수행됩니다.

예제 5-4 하드웨어에서 부동 소수점 연산 지원

||foo|| PROCVADD.F32 s2, s0, s1VMUL.F32 s0, s1, s1VSUB.F32 s0, s0, s2BX lrENDP

5-34 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 133: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

실제로 부동 소수점 산술에 대한 하드웨어 지원을 활용하는 코드는 더 간결하고 소프트웨어에서 부동 소수점 산술을 수행하는 코드보다 더 나은 성능을 제공합니다. 그러나 부동 소수점 산술에 대한 하드웨어 지원에서는 VFP 보조 프로세서가 필요합니다.

기본적으로 VFP 보조 프로세서가 있으면 VFP 명령어가 생성됩니다. VFP 보조 프로세서가 없는 경우에는 컴파일러가 소프트웨어 부동 소수점 라이브러리 fplib를 호출하는 코드를 생성하여 부동 소수점 연산을 수행합니다. fplib는 C 라이브러리의 RealView Development Suite 표준 배포 일부분으로 사용 가능합니다.

5.6.2 VFP 아키텍처

VFP는 단정밀도와 배정밀도 작업을 제공하는 부동 소수점 아키텍처입니다. 대부분의 작업은 스칼라 형식 또는 벡터 형식으로 이루어질 수 있습니다. 다음을 포함하여 아키텍처의 여러 가지 버전이 지원됩니다.

• 다음에서 구현되는 VFPv2

— ARM10200E가 제공하는 VFP10 수정 버전 1

— ARM926E/946E/966E에 대해 별도로 허가된 옵션으로 사용되는 VFP9-S

— ARM1136JF-S, ARM1176JZF-S 및 ARM11 MPCore에서 제공되는 VFP11

• ARM 아키텍처 버전 7 이상(예: Cortex-A8)에서 구현되는 VFPv3. VFPv3은 부동 소수점 예외를 트래핑할 수 없다는 점을 제외하고 VFPv2와 호환됩니다. 소프트웨어 지원 코드가 필요하지 않습니다. VFPv3에는 32개의 배정밀도 레지스터가 있습니다.

• 반정밀도 확장을 통해 선택적으로 확장된 VFPv3. 이러한 확장은 반정밀도 부동 소수점 숫자와 단정밀도 부동 소수점 숫자 간의 양방향 변환 기능을 제공하며, 단정밀도 부동 소수점 숫자를 지원하는 고급 SIMD 및 VFP 구현을 통해 구현할 수 있습니다.

• VFPv3-D16은 16개의 배정밀도 레지스터를 지공하는 VFPv3 구현으로, NEON 없이 VFP를 지원하는 ARM 아키텍처 버전 7 프로세서에서 구현됩니다.

• VFPv3U는 부동 소수점 예외를 트래핑할 수 있는 VFPv3의 구현입니다. 소프트웨어 지원 코드가 필요합니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-35ID090708 Non-Confidential, Unrestricted Access

Page 134: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

참고

VFP 아키텍처의 특정 구현은 추가적인 구현 관련 기능을 제공할 수 있습니다. 예를 들어 VFP 보조 프로세서 하드웨어에는 예외적 조건을 설명하기 위한 추가 레지스터가 포함될 수 있습니다. 이 추가 기능은 하위 아키텍처 기능으로 알려져 있습니다. 하부 아키텍처 기능에 대한 자세한 내용은 ARM Application Note 133 - Using VFP with RVDS를 참조하십시오. 이 Application Note는 install_directory\RVDS\Examples\...\vfpsupport의 RealView Development Suite 배포에 있는 Examples 디렉토리의 vfpsupport 하위 디렉토리에 있습니다.

5.6.3 VFP 지원

ARM VFP 보조 프로세서는 최적화되어 하드웨어에서 잘 정의된 부동 소수점 코드를 처리합니다. 너무 드물게 발생하거나 또는 너무 복잡한 산술 연산은 하드웨어에서 처리되지 않습니다. 대신 이러한 경우의 처리는 소프트웨어에서 처리되어야 합니다. 이 접근법은 보조 프로세서 하드웨어의 필요량을 최소화하고 비용을 절감합니다.

VFP 하드웨어가 처리할 수 없는 경우를 처리하기 위해 제공된 코드는 VFP 지원 코드로 알려져 있습니다. VFP 하드웨어가 상황을 직접 처리하지 못하면 추가 프로세싱을 위해 VFP 지원 코드로 중계합니다. 예를 들어 다음 중 하나를 처리하기 위해 VFP 지원 코드를 호출할 수 있습니다.

• NaN 관련된 부동 소수점 연산

• 비정규 값과 관련된 부동 소수점 연산

• 부동 소수점 오버플로

• 부동 소수점 언더플로

• 정확하지 않은 결과

• 0으로 나누기 오류

• 잘못된 연산

지원 코드가 있을 경우 VFP는 IEEE 754와 완전히 호환되는 부동 소수점 모델을 지원합니다.

VFP 지원 사용

편의를 위해 시스템에 사용할 수 있는 VFP 지원 코드의 구현은 RVCT 설치와 함께 제공됩니다. 지원 코드는 다음으로 구성됩니다.

• 하드웨어에 의해 중계되는 VFP 연산을 에뮬레이션하기 위한 라이브러리 vfpsupport.l 및 vfpsupport.b

5-36 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 135: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

이 파일은 RVCT 설치의 \lib\armlib 하위 디렉토리에 있습니다.

• 최상위 수준, 2차 수준 및 사용자 수준 인터럽트 처리기를 구현하는 C 소스 코드와 어셈블리 언어 소스 코드

이 파일은 install_directory\RVDS\Examples\...\vfpsupport의 RealView

Development Suite 배포에 있는 Examples 디렉토리의 vfpsupport 하위 디렉토리에 있습니다.

VFP 지원을 운영 체제와 통합하려면 이들 파일을 수정해야 할 수 있습니다.

• VFP 보조 프로세서의 하위 아키텍처 기능에 액세스하기 위한 C 소스 코드와 어셈블리 언어 소스 코드

이 파일은 install_directory\RVDS\Examples\...\vfpsupport의 RealView

Development Suite 배포에 있는 Examples 디렉토리의 vfpsupport 하위 디렉토리에 있습니다.

VFP 보조 프로세서가 명령어를 중계할 때 정의되지 않는 명령어 예외를 프로세서에 알리고 정의되지 않는 명령어 벡터를 통해 VFP 지원 코드가 수행됩니다. 최상위 수준과 2차 수준 인터럽트 처리기는 신호의 초기 처리를 수행하여, 예를 들어 예외가 잘못된 명령어에 의해 발생되지 않게 합니다. 그런 다음 사용자 수준 인터럽트 처리기는 라이브러리 vfpsupport.l 또는 vfpsupport.b에서 적절한 라이브러리 함수를 호출하여 소프트웨어에서 VFP 연산을 에뮬레이션합니다.

참고

다음과 같은 경우 VFP 지원 코드를 사용할 필요가 없습니다.

• 일반적이지 않거나 예외적인 상황의 트래핑이 필요하지 않은 경우

• VFP 보조 프로세서가 RunFast 모드에서 작동하는 경우

• 하드웨어 보조 프로세서가 VFPv3 기반 시스템일 경우

RVCT 설치와 함께 공급된 VFP 지원 코드 사용에 대한 자세한 내용은 ARM Application Note 133 - Using VFP with RVDS를 참조하십시오. 이 Application Note는 install_directory\RVDS\Examples\...\vfpsupport의 RealView Development Suite 배

포에 있는 Examples 디렉토리의 vfpsupport 하위 디렉토리에 있습니다.

5.6.4 단정밀도 부동 소수점 숫자 지원

반정밀도 부동 소수점 숫자는 VFPv3 아키텍처에 대한 선택적 확장으로 제공됩니다. VFPv3 보조 프로세서를 사용할 수 없거나 이 확장이 없는 VFPv3 보조 프로세서를 사용하는 경우 이 확장은 부동 소수점 라이브러리 fplib를 통해 지원됩니다.

반정밀도 부동 소수점 숫자는 fp16_format 명령 행 옵션으로 선택한 경우에만 사용할 수 있습니다. 컴파일러 참조 설명서의 2-62페이지의 --fp16_format=format를 참조하십시오.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-37ID090708 Non-Confidential, Unrestricted Access

Page 136: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

사용 가능한 반정밀도 부동 소수점 형식은 ieee 및 alternative입니다. 두 형식에서 16비트 숫자의 기본 레이아웃은 같습니다. 자세한 내용은 그림 5-1을 참조하십시오.

그림 5-1 반정밀도 부동 소수점 형식

인수 설명:

S (bit[15]): Sign bitE (bits[14:10]): Biased exponentT (bits[9:0]): Mantissa.

이러한 필드의 의미는 선택하는 형식에 따라 달라집니다.

IEEE 반정밀도

IF E==31:IF T==0: Value = Signed infinityIF T!=0: Value = Nan

T[9] determines Quiet or Signalling:0: Quiet NaN1: Signalling NaN

IF 0<E<31:Value = (-1)Sx2(E-15)x(1+2-10T)

IF E==0:IF T==0: Value = Signed zeroIF T!=0: Value = (-1)Sx2(-14)x(0+2-10T)

대체 반정밀도

IF 0<E<32:Value = (-1)Sx2(E-15)x(1+2-10T)

IF E==0:IF T==0: Value = Signed zeroIF T!=0: Value = (-1)Sx2(-14)x(0+2-10T)

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

S E T

5-38 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 137: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

사용 제한

__fp16 형식 사용 시에는 다음 제한이 적용됩니다.

• C 또는 C++ 식에서 사용하는 경우 __fp16 형식은 단정밀도로 승격됩니다. 그리고 피연산자 중 하나에서 필요로 하는 경우 배정밀도로 승격될 수도 있습니다.

• 단정밀도 값을 __fp16으로 변환할 수 있습니다. 배정밀도 값은 단정밀도로 변환된 다음 __fp16으로 변환되는데, 이 경우 반올림이 두 번 적용될 수 있습니다. ARM 아키텍처에서는 직접 배정밀도에서 16비트로 변환할 수 없기 때문입니다.

• fpmode=fast를 사용하는 경우에는 반정밀도 부동 소수점 형식에서 또는 해당 형식으로 변환할 때 부동 소수점 예외가 발생하지 않습니다.

• 함수 형식적 인수는 __fp16 형식일 수 없습니다. 그러나 __fp16 형식 변수에 대한 포인터를 함수 형식적 인수 형식으로 사용할 수는 있습니다.

• __fp16 값을 실제 함수 인수로 전달할 수 있습니다. 이 경우에는 값이 단정밀도 값으로 변환됩니다.

• __fp16은 함수의 반환 형식으로 지정할 수 없습니다. 그러나 __fp16 형식에 대한 포인터를 반환 형식으로 사용할 수는 있습니다.

• __fp16 값은 float 또는 double을 반환하는 함수의 반환 값으로 사용될 때 단정밀도 또는 배정밀도 값으로 변환됩니다.

이름 자르기

반정밀도 데이터 형식에 대한 C++ 이름 자르기는 C++ 일반 ABI에서 지정됩니다. ARM 아키텍처용 C++ ABI를 참조하십시오.

5.6.5 부동 소수점 계산 및 연결

부동 소수점 계산과 연결 간의 차이를 파악해야 합니다. 부동 소수점 계산은 하드웨어 보조 프로세서 명령어 또는 라이브러리 함수를 통해 수행하는 반면, 부동 소수점 연결은 부동 소수점 값을 사용하는 함수 간에 인수를 전달하는 방식과 관련된 작업입니다.

부동 소수점 연결 형식은 다음과 같습니다.

• 소프트웨어 부동 소수점 연결

• 하드웨어 부동 소수점 연결

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-39ID090708 Non-Confidential, Unrestricted Access

Page 138: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

소프트웨어 부동 소수점 연결은 함수의 매개변수 및 반환 값이 ARM 정수 레지스터 r0 ~ r3 및 스택을 사용하여 전달됨을 의미합니다.

하드웨어 부동 소수점 연결은 VFP 보조 프로세서 레지스터를 사용하여 인수 및 반환 값을 전달합니다. VFP 보조 프로세서 레지스터에 대한 자세한 내용은 ARM 아키텍처용 ARM 프로시저 호출 표준(ARM IHI0042)을 참조하십시오.

소프트웨어 부동 소수점 연결을 사용하는 경우 결과로 생성되는 코드를 VFP 보조 프로세서의 유무에 관계없이 코어에서 실행할 수 있다는 장점이 있습니다. 즉, VFP 하드웨어 보조 프로세서의 유무에 관계없이 코드를 실행 및 사용할 수 있습니다.

하드웨어 부동 소수점 연결을 사용하는 경우 소프트웨어 부동 소수점 연결을 사용하는 경우에 비해 효율성은 높아지지만 VFP 보조 프로세서가 있어야 합니다.

표 5-12에서는 부동 소수점 연결 형식에 대해 사용 가능한 컴파일러 옵션과 필요한 부동 소수점 계산 형식을 보여 줍니다.

표 5-12 부동 소수점 연결 및 계산을 위한 컴파일러 옵션

연결 계산

컴파일러 옵션하드웨어 부동 소수점 연결

소프트웨어 부동 소수점 연결

하드웨어 부동 소수점 보조 프로세서

소프트웨어 부동 소수점 라이브러리(fplib)

아니요 예 아니요 예 --fpu=softvfp

아니요 예 예 아니요 --fpu=softvfp+vfpv2--fpu=softvfp+vfpv3--fpu=softvfp+vfpv3_fp16--fpu=softvfp+vfpv3_d16--fpu=softvfp+vfp3_d16_fp16

예 아니요 예 아니요 --fpu=vfp--fpu=vfpv2--fpu=vfpv3--fpu=vfpv3_fp16--fpu=vfpv3_dp16--fpu=vfpv3_d16_fp16

5-40 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 139: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

softvfp는 소프트웨어 부동 소수점 연결을 지정합니다. 소프트웨어 부동 소수점 연결이 사용되는 경우 다음을 수행해야 합니다.

• --softvfp, --fpu softvfp+vfpv2, --fpu softvfp+vfpv3, --fpu softvfp+vfpv3_fp16, softvfp+vfpv3_d16 또는 softvfp+vfpv3_d16_fp16 옵션 중 하나를 사용하여 호출하는 함수 및 호출되는 함수를 컴파일해야 합니다.

• 호출하는 함수와 호출된 함수를 __softfp 키워드를 사용하여 선언해야 합니다.

각 --fpu softvfp, --fpu softvfp+vfpv2,--fpu softvfp+vfpv3, --fpu softvfp+vfpv3_fp16, --fpu softvfpv3_d16 및 --fpu softvfpv3_d16_fp16 옵션은 전체 파일에 대해 소프트웨어 부동 소수점 연결을 지정합니다. 반면에 __softfp 키워드는 함수별로 소프트웨어 부동 소수점 연결을 지정할 수 있게 합니다.

참고

별도의 컴파일러 옵션을 사용하여 필요한 부동 소수점 연결 형식 및 부동 소수점 계산 형식을 선택하는 대신, 하나의 컴파일러 옵션(--fpu)을 사용하여 두 가지를 모두 선택할 수 있습니다. 5-40페이지의 표 5-12를 참조하십시오. 예를 들어 --fpu=softvfp+vfpv2는 소프트웨어 부동 소수점 연결과 계산을 위한 하드웨어 보조 프로세서를 선택합니다. softvfp를 사용할 때마다 소프트웨어 부동 소수점 연결이 지정됩니다.

다음을 참조하십시오.

• 컴파일러 참조 설명서의 2-65페이지의 --fpu=name

• 컴파일러 참조 설명서의 4-17페이지의 __softfp

• 컴파일러 참조 설명서의 4-71페이지의 #pragma softfp_linkage, #pragma no_softfp_linkage

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-41ID090708 Non-Confidential, Unrestricted Access

Page 140: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

5.7 0으로 나누기 오류 트래핑 및 확인

특히 쉽게 복구할 수 없는 임베디드 시스템의 경우 코드에서 0으로 나누기 오류를 제거하는 것은 중요합니다. ARM 프로세서 코어의 경우 0으로 나누기 오류는 다음과 같은 범주로 구분됩니다.

• 정수 0으로 나누기 오류

• (소프트웨어) 부동 소수점 0으로 나누기 오류

이러한 오류를 트래핑하고 확인하기 위한 두 가지 경우에서 다른 기법이 필요합니다.

5.7.1 정수 나누기

정수 0으로 나누기 오류는 적절한 C 라이브러리 도우미 함수를 다시 구현하여 트래핑하고 확인할 수 있습니다.

0으로 나누기가 발생하는 경우 기본 동작은 신호 함수가 사용될 때나 __rt_raise 또는 __aeabi_idiv0이 다시 구현될 때 __aeabi_idiv0을 호출하는 것입니다. 그렇지 않으면 나누기 함수에서 0이 반환됩니다.

__aeabi_idiv0은 추가 인수 DIVBYZERO를 사용하여 SIGFPE를 발생시킵니다.

코드에서 0으로 나누기 오류 트래핑

다음과 같은 방법으로 정수 0으로 나누기 오류를 트래핑할 수 있습니다.

• 0으로 나누면 표준 결과(예: 0)가 반환되도록 C 라이브러리 도우미 함수 __aeabi_idiv0을 다시 구현합니다.

정수 나누기는 C 라이브러리 도우미 함수 __aeabi_idiv 및 __aeabi_uidiv를 통해 코드에서 구현됩니다. 두 함수 모두 0으로 나누기를 확인합니다.

정수 0으로 나누기가 감지되면 __aeabi_idiv0으로 분기됩니다. 따라서 0으로 나누기를 트래핑하려면 __aeabi_idiv0에 브레이크포인트를 배치하기만 하면 됩니다.

AEABI 함수 __aeabi_idiv, __aeabi_uidiv 및 __aeabi_idiv0에 대한 자세한 내용은 ARM 아키텍처용 런타임 ABI를 참조하십시오. 이 내용은 http://www.arm.com/products/DevTools/ABI.html에 나와 있습니다.

• C 라이브러리 도우미 함수 __rt_raise를 다시 구현하여 신호를 처리합니다.

5-42 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 141: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

기본적으로 정수를 0으로 나누면 신호가 발생합니다. 따라서 0으로 나누기를 차단하려면 __rt_raise를 다시 구현할 수 있습니다. 이 함수의 프로토타입은 다음과 같습니다.

void __rt_raise(int signal, int type)

0으로 나누기 오류가 발생하면 __aeabi_idiv0은 __rt_raise(2, 2)를 호출합니다. 따라서 __rt_raise 구현에서 (signal == 2) && (type == 2)를 확인하여 0으로 나누기가 발생했는지 확인해야 합니다.

다음을 참조하십시오.

— 라이브러리 설명서의 2-28페이지의 정수 및 부동 소수점 도우미 함수

— 라이브러리 설명서의 2-30페이지의 C 라이브러리 사용

— 라이브러리 설명서의 2-66페이지의 오류 신호, 오류 처리 및 프로그램 종료 조정

— 라이브러리 설명서의 2-70페이지의 __rt_raise()

• 신호 함수를 사용하여 SIGFPE용 처리기를 설치합니다. 이 방법을 사용하면 앞서 설명한 다른 방법에 비해 이식성은 높아지지만 효율성은 떨어집니다.

코드에서 0으로 나누기 오류 확인

__aeabi_idiv0에 대한 엔트리에서 링크 레지스터 LR는 응용 프로그램 코드에서 __aeabi_uidiv 나누기 루틴에 대한 호출 후에 명령어의 주소를 포함합니다. 소스 코드에서 문제를 일으키는 행을 식별하려면 LR이 제공한 주소에서 디버거의 C 코드 라인을 조회하면 됩니다.

매개변수 검사

사후 디버깅을 위한 매개변수를 확인 및 저장하려면 __aeabi_idiv0을 트래핑하면 됩니다. __aeabi_idiv0 및 $Super$$ 메커니즘을 사용하면 $Sub$$에 대한 모든 호출에 개입할 수 있습니다.

$Super$$ 패치되지 않은 원래 함수 __aeabi_idiv0을 식별하기 위해 $Super$$를 __aeabi_idiv0의 접두사로 사용합니다. 이 접두사를 사용하면 원래 함수를 직접 호출할 수 있습니다.

$Sub$$ 원래 버전의 __aeabi_idiv0 대신에 호출할 새 함수를 식별하기 위해 $Sub$$를 __aeabi_idiv0의 접두사로 사용합니다. 이 접두사를 사용하면 원래 함수 __aeabi_idiv0의 앞이나 뒤에 처리를 추가할 수 있습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-43ID090708 Non-Confidential, Unrestricted Access

Page 142: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

예제 5-5는 $Super$$ 및 $Sub$$ 메커니즘을 사용하여 __aeabi_div0을 인터셉트합니다. 링커 사용 설명서의 4-14페이지의 $Super$$ 및 $Sub$$를 사용하여 기호 정의 재정의를 참조하십시오.

예제 5-5 $Super$$ 및 $Sub$$를 사용하여 __aeabi_div0 인터셉트

extern void $Super$$__aeabi_idiv0(void);/* this function is called instead of the original __aeabi_idiv0() */void $Sub$$__aeabi_idiv0(){

// insert code to process a divide by zero...// call the original __aeabi_idiv0 function$Super$$__aeabi_idiv0();

}

5.7.2 (소프트웨어) 부동 소수점 나누기

소프트웨어의 부동 소수점 0으로 나누기 오류는 내장 함수와 C 라이브러리의 조합을 사용하여 트래핑하고 식별할 수 있습니다.

코드에서 0으로 나누기 오류 트래핑

코드에서 부동 소수점 0으로 나누기 오류를 트래핑하려면 내장 함수를 사용합니다.

__ieee_status(FE_IEEE_MASK_ALL_EXCEPT, FE_IEEE_MASK_DIVBYZERO);

이는 코드의 모든 0으로 나누기 오류를 트래핑하고 예제 5-6에 나와 있는 것처럼 다른 모든 예외를 언트래핑합니다.

예제 5-6 0으로 나누기 오류

#include <stdio.h>#include <fenv.h>

int main(void){ float a, b, c;

// Trap the Invalid Operation exception and untrap all other exceptions:__ieee_status(FE_IEEE_MASK_ALL_EXCEPT, FE_IEEE_MASK_DIVBYZERO);c = 0;

5-44 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 143: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

a = b / c;printf("b / c = %f, ", a); // trap division-by-zero errorreturn 0;

}

코드에서 0으로 나누기 오류 확인

예외가 발생할 때마다 C 라이브러리 도우미 함수 _fp_trapveneer가 호출됩니다. 이 함수에 대한 엔트리에서 레지스터의 상태는 예외가 발생했을 때부터 변경되지 않습니다. 따라서 응용 프로그램 코드에서 예외로 이어졌던 산술 연산이 포함된 함수 주소를 찾으려면 함수 _fp_trapveneer에 브레이크포인트를 배치하고 LR에서 살펴보면 됩니다.

예를 들어 5-44페이지의 예제 5-6의 C 코드가 다음 문자열을 사용하여 명령 행에서 컴파일된다고 가정합니다.

armcc --fpmode ieee_full

컴파일러에 의해 생성된 어셈블리 언어 코드가 디스어셈블되면 RealView 디버거는 예제 5-7에 나와 있는 출력을 생성합니다.

예제 5-7 0으로 나누기 오류의 디스어셈블리

main:00008080 E92D4010 PUSH {r4,lr}00008084 E3A01C02 MOV r1,#0x20000008088 E3A00C9F MOV r0,#0x9f000000808C EB000F1A BL __ieee_status <0xbcfc>00008090 E59F0020 LDR r0,0x80b8 00008094 E3A01000 MOV r1,#000008098 EB000DEA BL _fdiv <0xb848>0000809C EB000DBD BL _f2d <0xb798>000080A0 E1A02000 MOV r2,r0000080A4 E1A03001 MOV r3,r1000080A8 E28F000C ADR r0,{pc}+0x14 ; 0x80bc000080AC EB000006 BL __0printf <0x80cc>000080B0 E3A00000 MOV r0,#0000080B4 E8BD8010 POP {r4,pc}000080B8 40A00000 <Data> 0x00 0x00 0xA0 '@'000080BC 202F2062 <Data> 'b' ' ' '/' ' '000080C0 203D2063 <Data> 'c' ' ' '=' ' '000080C4 202C6625 <Data> '%' 'f' ',' ' '000080C8 00000000 <Data> 0x00 0x00 0x00 0x00

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-45ID090708 Non-Confidential, Unrestricted Access

Page 144: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

_fp_trapveneer에 브레이크포인트를 배치하고 디버그 모니터에서 디스어셈블리를 실행하면 다음이 생성됩니다.

> goStopped at 0x0000BF6C due to SW Instruction BreakpointStopped at 0x0000BF6C: TRAPV_S\_fp_trapveneer

레지스터의 검사가 다음과 같이 표시됩니다.

r0: 0x40A00000 r1: 0x00000000 r2: 0x00000000 r3: 0x00000000r4: 0x0000C1DC r5: 0x0000C1CC r6: 0x00000000 r7: 0x00000000r8: 0x00000000 r9: 0x00000000 r10: 0x0000C0D4 r11: 0x00000000r12: 0x08000004 SP: 0x07FFFFF8 LR: 0x0000809C PC: 0x0000BF6CCPSR: nzcvIFtSVC

링크 레지스터 LR에 포함된 주소가 0x809c로 설정된 경우 BL _fdiv 명령어 뒤에 나오는 명령어 주소는 예외가 됩니다.

매개변수 검사

사후 디버깅을 위한 매개변수를 저장하려면 _fp_trapveneer를 인터셉트해야 합니다. _fp_trapveneer에 대한 모든 호출에 개입하려면 $Super$$ 및 $Sub$$ 메커니즘을 사용하십시오. 예를 들어 다음과 같습니다.

AREA foo, CODEIMPORT |$Super$$_fp_trapveneer|EXPORT |$Sub$$_fp_trapveneer|

|$Sub$$_fp_trapveneer|;; Add code to save whatever registers you require here;; Take care not to corrupt any needed registers

B |$Super$$_fp_trapveneer|END

다음을 참조하십시오.

• 5-42페이지의 정수 나누기

• 링커 사용 설명서의 4-14페이지의 $Super$$ 및 $Sub$$를 사용하여 기호 정의 재정의

5-46 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 145: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

5.8 C99의 새로운 기능

1999 C 표준은 다음과 같은 다양한 기능을 C에 새로 제공합니다.

• 새로운 키워드 및 식별자 등의 새로운 언어 기능과 기존 C90 언어용 확장 구문

• 새 라이브러리와 기존 C90 라이브러리용 새 매크로 및 함수 등의 새로운 라이브러리 기능

C99의 새로운 기능 중 C99를 처음 사용하는 개발자에게 유용한 기능에 대해서는 다음 단원에서 설명합니다.

참고

C90은 몇 가지 특별한 경우를 제외하고 표준 C++에 지정된 언어가 C++의 하위 세트이기 때문에 표준 C++와 호환됩니다. C99 표준의 새로운 기능은 이러한 점에서 C99가 C++와 더 이상 호환되지 않는다는 것을 의미합니다.

5.8.1 언어 기능

C99 표준은 여러 가지 새로운 언어 기능을 제공합니다. 예를 들면 다음과 같습니다.

• GNU 컴파일러에 제공된 C90의 확장과 유사한 일부 기능(예: 가변적인 개수의 인수가 있는 매크로)

참고

GNU 컴파일러에 있는 C90 확장의 구현은 C99에 있는 유사한 기능의 구현과 항상 호환되지는 않습니다.

• C++에서 사용할 수 있는 일부 기능(예: // 주석 및 선언과 코드를 혼합하는 기능)

• 일부 완전히 새로운 기능(예: 복합 숫자 제한된 포인터 및 지정된 이니셜라이저)

C99의 새로운 언어 기능 중 특별히 더 유용한 기능에 대해서는 다음 단원에서 설명합니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-47ID090708 Non-Confidential, Unrestricted Access

Page 146: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

// 주석

//을 사용하여 C++에서처럼 1라인 주석의 시작을 표시할 수 있습니다. 컴파일러 참조 설명서의 3-5페이지의 // 주석을 참조하십시오.

복합 리터럴

ISO C99는 복합 리터럴을 지원합니다. 복합 문자열은 이니셜라이저 앞에 오는 캐스트와 유사합니다. 값은 캐스트에 지정되는 유형의 객체며, 이니셜라이저에 지정된 요소를 포함합니다. 값은 lvalue입니다. 예를 들면 다음과 같습니다.

int y[] = (int []) {1, 2, 3}; int z[] = (int [3]) {1};

지정된 이니셜라이저

C90에서는 배열, 구조체 또는 공용체의 특정 구성원을 초기화할 수 없습니다. 그러나 C99에서는 지정된 이니셜라이저를 사용하여 이름 또는 첨자별로 배열, 구조체 또는 공용체의 특정 구성원을 초기화할 수 있습니다. 예를 들면 다음과 같습니다.

typedef struct{

char *name;int rank;

} data;data vars[10] = { [0].name = "foo", [0].rank = 1,

[1].name = "bar", [1].rank = 2,[2].name = "baz", [3].name = "gazonk" };

명시적으로 초기화되지 않은 집계 구성원은 기본적으로 0으로 초기화됩니다.

Hex floats

C99는 16진수 형식으로 작성할 수 있는 부동 소수점 숫자를 지원합니다. 예를 들면 다음과 같습니다.

float hex_floats(void){ return 0x1.fp3; // 1 15/16 * 2^3}

16진수 형식에서 지수는 10진수로 의미를 가진 부분을 곱하는 2의 거듭제곱을 의미합니다 (예: 0x1.fp3 = 1.9375 * 8 = 1.55e1).

5-48 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 147: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

유연한 배열 구성원

구성원이 둘 이상인 struct에서 struct의 마지막 구성원은 불완전한 배열 유형을 가질 수 있습니다. 이러한 구성원을 struct의 유연한 배열 구성원이라고 합니다.

참고

struct에 유연한 배열 구성원이 있으면 전체 struct의 유형이 불완전한 유형이 됩니다.

유연한 배열 구성원을 사용하면 배열 크기 지정을 런타임으로 연기할 수 있기 때문에 C에서 동적 유형 지정을 에뮬레이션할 수 있습니다. 예를 들면 다음과 같습니다.

extern const int n;typedef struct{

int len;char p[];

} str;void foo(void){

size_t str_size = sizeof(str); // equivalent to offsetoff(str, p)str *s = malloc(str_size + (sizeof(char) * n));

}

__func__ 사전 정의된 식별자

__func__ 사전 정의된 식별자를 사용하면 현재 함수의 이름을 가져올 수 있습니다. 예를 들어 다음과 같은 함수가 있다고 가정합니다.

void foo(void){

printf("This function is called '%s'.\n", __func__);}

이 함수는 다음을 인쇄합니다.

This function is called 'foo'.

inline 함수

C99 키워드 inline은 inline으로 정규화된 함수의 호출을 인라인으로 확장하도록 컴파일러에 지시합니다. 예를 들면 다음과 같습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-49ID090708 Non-Confidential, Unrestricted Access

Page 148: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

inline int max(int a, int b){

return (a > b) ? a : b;}

컴파일러는 합당한 이유가 있는 경우에만 inline으로 정규화된 함수를 인라인합니다. 함수를 인라인하면 성능에 악영향을 주는 경우 이러한 지시를 무시할 수 있습니다. 자세한 내용은 5-18페이지의 함수 인라인을 참조하십시오.

참고

C99의 inline과 표준 C++의 inline은 서로 다른 의미를 갖습니다.

long long 데이터 유형

C99는 정수 데이터 유형 long long을 지원합니다. 이 형식은 RVCT에서 64비트입니다. 예를 들면 다음과 같습니다.

long long int j = 25902068371200; // length of light day, metersunsigned long long int i = 94607304725808000ULL; // length of light year, meters

컴파일러 참조 설명서의 3-8페이지의 long long을 참조하십시오.

가변적인 개수의 인수가 있는 매크로

C99에서는 가변적인 개수의 인수를 허용하는 매크로를 선언할 수 있습니다. 이러한 매크로를 정의하는 구문은 함수 구문과 유사합니다. 예를 들면 다음과 같습니다.

#define debug(format, ...) fprintf (stderr, format, __VA_ARGS__)void Variadic_Macros_0(){ debug ("a test string is printed out along with %x %x %x\n", 12, 14, 20);}

혼합된 선언 및 코드

C99를 사용하면 C++에서처럼 복합문에서 선언과 코드를 혼합할 수 있습니다. 예를 들어 다음과 같습니다.

void foo(float i){

i = (i > 0) ? -i : i;float j = sqrt(i); // illegal in C90

}

5-50 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 149: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

선택 및 이터레이션 문을 위한 새로운 블록 범위

for 루프에서 첫 번째 식을 C++에서처럼 선언할 수 있습니다. 선언 범위는 루프 본문까지만 확장됩니다. 예를 들면 다음과 같습니다.

extern int max;for (int n = max - 1; n >= 0; n--){

// body of loop}

이것은 다음과 같습니다.

extern int max;{

int n = max - 1;for (; n >= 0; n--){

// body of loop }}

참고

C++에서와 달리 for 테스트, if 테스트 또는 switch 식에서는 새로운 선언을 사용할 수 없습니다.

_Pragma 사전 처리 연산자

C90에서는 매크로 식의 결과로 #pragma 지시어를 생성할 수 없습니다. C99 _Pragma 연산자를 사용하면 pragma 지시어에 사전 처리기 매크로를 삽입할 수 있습니다. 예를 들면 다음과 같습니다.

# define RWDATA(X) PRAGMA(arm section rwdata=#X)# define PRAGMA(X) _Pragma(#X)RWDATA(foo) // same as #pragma arm section rwdata="foo"int y = 1; // y is placed in section "foo"

제한된 포인터

C99 키워드 restrict를 사용하면 다양한 객체 포인터 유형과 함수 매개변수 배열이 메모리의 중복 영역을 가리키지 않도록 할 수 있습니다. 이렇게 하면 컴파일러에서 별칭 지정 가능성 때문에 다른 방식으로 방해받을 수도 있는 최적화 작업을 수행할 수 있습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-51ID090708 Non-Confidential, Unrestricted Access

Page 150: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

다음 예제에서 a 포인터는 b 포인터와 동일한 영역의 메모리를 가리키지도 않고 가리킬 수도 없습니다.

void copy_array(int n, int *restrict a, int *restrict b){ while (n-- > 0) *a++ = *b++;}void test(void){ extern int array[100]; copy_array(50, array + 50, array); // valid copy_array(50, array + 1, array); // undefined behavior}

그러나 restrict로 정규화된 포인터는 서로 다른 배열이나 배열 내의 서로 다른 영역을 가리킬 수 있습니다.

5.8.2 새로운 기능

C99 표준은 프로그래머를 위한 여러 가지 새로운 라이브러리 기능을 제공합니다. 예를 들면 다음과 같습니다.

• UNIX 표준 라이브러리에 제공된 C90 표준 라이브러리의 확장과 유사한 일부 기능(예: snprintf 계열의 함수)

• 완전히 새로운 일부 라이브러리 기능(예: <fenv.h>에 제공된 표준화된 부동 소수점 환경)

C99의 새로운 라이브러리 기능 중 특별히 더 유용한 기능에 대해서는 다음 단원에서 설명합니다.

<math.h>의 추가 산술 라이브러리

C99는 해당 C90 표준 헤더에 없는 표준 헤더 <math.h>의 추가 매크로, 유형 및 함수를 지원합니다.

C90에는 없지만 C99에 새로 추가된 매크로에는 다음과 같은 것들이 있습니다.

INFINITY // positive infinityNAN // IEEE not-a-number

C90에는 없지만 C99에 새로 추가된 일반 함수 매크로에는 다음과 같은 것들이 있습니다.

5-52 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 151: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

#define isinf(x) // non-zero only if x is positive or negative infinity#define isnan(x) // non-zero only if x is NaN#define isless(x, y) // 1 only if x < y and x and y are not NaN, and 0 otherwise#define isunordered(x, y) // 1 only if either x or y is NaN, and 0 otherwise

C90에는 없지만 C99에 새로 추가된 산술 함수에는 다음과 같은 것들이 있습니다.

double acosh(double x); // hyperbolic arccosine of xdouble asinh(double x); // hyperbolic arcsine of xdouble atanh(double x); // hyperbolic arctangent of xdouble erf(double x); // returns the error function of xdouble round(double x); // returns x rounded to the nearest integerdouble tgamma(double x); // returns the gamma function of x

C99는 모든 실제 부동 소수점 유형에 대해 새로운 산술 함수를 지원합니다.

또한 기존의 모든 <math.h> 함수의 단정밀도 버전도 지원합니다.

복합 숫자

C99 모드에서는 컴파일러가 복합 숫자 및 허수를 지원합니다. GNU 모드에서는 컴파일러가 복합 숫자만 지원합니다.

예를 들면 다음과 같습니다.

#include <stdio.h>#include <complex.h>

int main(void){

complex float z = 64.0 + 64.0*I;printf(“z = %f + %fI\n” , creal(z), cimag(z));return 0;

}

복합 형식은 다음과 같습니다.

• 부동 복합

• 이중 복합

• long 이중 복합.

bool 유형 및 <stdbool.h>

C99는 네이티브 유형 _Bool을 새로 제공하고, 연관된 표준 헤더 <stdbool.h>는 bool 테스트를 위한 bool, true 및 false를 새로 제공합니다. 예를 들면 다음과 같습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-53ID090708 Non-Confidential, Unrestricted Access

Page 152: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

#include <stdbool.h>bool foo(FILE *str){

bool err = false;...if (!fflush(str)){

err = true;}...return err;

}

참고

bool의 C99 의미는 C++의 의미와 일치시키기 위한 것입니다.

<inttypes.h> 및 <stdint.h>의 확장된 정수 유형 및 함수

C90에서는 long 데이터 형식이 최대 정수 형식 및 32비트 컨테이너 역할을 둘 다 수행할 수 있습니다. C99에서는 새로운 표준 라이브러리 헤더 파일 <inttypes.h> 및 <stdint.h>를 통해 이러한 모호함을 없앴습니다.

헤더 파일 <stdint.h>는 다음과 같은 새로운 유형을 제공합니다.

• 최대 폭 부호 있는 정수 유형 및 부호 없는 정수 유형인 intmax_t 및 uintmax_t

• 부호 있는 객체 포인터와 부호 없는 객체 포인트를 저장할 수 있는 intptr_t 및 unintptr_t

헤더 파일 <inttypes.h>는 intmax_t 유형의 값을 조작할 수 있는 라이브러리 함수를 제공합니다. 예를 들면 다음과 같습니다.

intmax_t imaxabs(intmax_t x); // absolute value of ximaxdiv_t imaxdiv(intmax_t x, intmax_t y) // returns the quotient and remainder

// of x / y

<fenv.h>의 부동 소수점 환경 액세스

C99 표준 헤더 파일 <fenv.h>를 사용하면 수치 제어 프로그래밍을 위해 IEEE 754 호환 부동 소수점 환경에 액세스할 수 있습니다. 이 라이브러리는 부동 소수점 상태를 관리 및 제어하기 위해 두 가지 유형과 다양한 매크로 및 함수를 새로 제공합니다.

5-54 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 153: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

다음은 새로 지원되는 유형입니다.

• 전체 부동 소수점 환경을 나타내는 fenv_t

• 부동 소수점 상태를 나타내는 fexcept_t

다음은 새로 지원되는 매크로입니다.

• 부동 소수점 예외를 관리하기 위한 FE_DIVBYZERO, FE_INEXACT, FE_INVALID, FE_OVERFLOW 및 FE_UNDERFLOW

• 표시된 반올림 방향에서 반올림을 관리하기 위한 FE_DOWNWARD, FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD

• 기본 부동 소수점 환경을 나타내는 FE_DFL_ENV

다음은 새로 지원되는 함수입니다.

int feclearexcept(int ex); // clear floating-point exceptions selected by exint feraiseexcept(int ex); // raise floating point exceptions selected by exint fetestexcept(int ex); // test floating point exceptions selected by xint fegetround(void); // return the current rounding modeint fesetround(int mode); // set the current rounding mode given by modeint fegetenv(fenv_t *penv); return the floating-point environment in penvint fesetenv(const fenv_t *penv); // set the floating-point environment to penv

<stdio.h>에 있는 snprintf 계열의 함수

C90 표준 헤더 <stdio.h>에 있는 sprintf 계열의 함수를 사용하는 것은 위험할 수 있습니다. 예를 들어 다음과 같은 문이 있다고 가정합니다.

sprintf(buffer, size, "Error %d: Cannot open file '%s'", errno, filename);

여기서 변수 size는 buffer에 삽입할 수 있는 최소 문자 수를 지정합니다. 따라서 문자열에 할당된 메모리보다 더 많은 수의 문자가 출력될 수 있습니다.

<stdio.h>의 C99 버전에 있는 snprintf 함수는 버퍼 오버런을 방지하는 sprintf 함수의 안전한 버전입니다. 예를 들어 다음과 같은 문이 있다고 가정합니다.

snprintf(buffer, size, "Error %d: Cannot open file '%s'", errno, filename);

여기서 변수 size는 buffer에 삽입할 수 있는 최대 문자 수를 지정합니다. 버퍼는 size에 지정된 크기보다 클 경우 오버런되지 않습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 5-55ID090708 Non-Confidential, Unrestricted Access

Page 154: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

코딩 방법

<tgmath.h>의 유형 일반 산술 매크로

새 표준 헤더 <tgmath.h>는 부동 소수점 형식에서 오버로드되는 형식 일반 수학 함수의 여러 가지 계열을 정의합니다. 예를 들어 삼각법 함수 cos는 다음과 같이 오버로드된 함수를 갖고 있는 것처럼 작동합니다.

extern float cos(float x);extern double cos(double x);extern long double cos(long double x);...

예를 들어 다음과 같은 문이 있다고 가정합니다.

p = cos(0.78539f); // p = cos(pi / 4)

이 문은 0.78539f 리터럴의 형식에 따라 단정밀도 버전의 cos 함수를 호출합니다.

참고

유형 일반 계열의 산술 함수는 연산자 오버로드 메커니즘을 사용하여 C++에서 정의할 수 있습니다. C++에서 연산자 오버로딩을 사용하여 정의한 형식 일반 계열의 함수와 <tgmath.h>에 정의된 해당 형식 일반 계열의 함수는 서로 다른 의미를 갖습니다.

<wchar.h>의 확장 문자 I/O 함수

C99에는 확장 문자 I/O 함수가 도입되어 일반 문자와 거의 동일한 방식으로 확장 문자를 파일에서 읽고 파일에 쓸 수 있습니다. ARM C 라이브러리는 wchar.h에 정의된 C99 함수를 모두 지원합니다. ISO/IEC 9899:TC2의 7.24 단원을 참조하십시오.

5-56 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 155: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

6장 진단 메시지

ARM 컴파일러에서는 잠재적 이식성 문제와 기타 위험에 대한 메시지를 표시합니다. 이 장에서는 다음 작업에 사용할 수 있는 컴파일러 옵션에 대해 설명합니다.

• 특정 메시지를 표시하지 않습니다. 예를 들어 이전 스타일 C로 작성된 프로그램을 포팅하는 초기 단계에서 경고를 표시하지 않을 수 있습니다. 그러나 일반적으로 메시지 기능을 해제하는 것보다 코드를 검사하는 것이 더 안전합니다.

• 특정 메시지의 심각도 변경

이 단원에는 다음 소단원이 포함되어 있습니다.

• 6-2페이지의 진단 리디렉션

• 6-3페이지의 진단 메시지의 심각도

• 6-4페이지의 진단 메시지의 출력 제어

• 6-5페이지의 진단 메시지 심각도 변경

• 6-6페이지의 진단 메시지 표시 안 함

• 6-7페이지의 진단 메시지의 접두사 문자

• 6-8페이지의 -W 옵션을 지정하여 경고 메시지를 표시하지 않음

• 6-9페이지의 상태 코드 종료 및 종료 메시지

• 6-10페이지의 데이터 흐름 경고

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 6-1ID090708 Non-Confidential, Unrestricted Access

Page 156: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

진단 메시지

6.1 진단 리디렉션

--errors=filename 옵션을 사용하여 컴파일러 진단 출력을 파일로 리디렉션할 수 있습니다. 명령 옵션과 연관된 진단은 리디렉션되지 않습니다.

자세한 내용은 6-4페이지의 진단 메시지의 출력 제어를 참조하십시오.

6-2 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 157: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

진단 메시지

6.2 진단 메시지의 심각도

표 6-1에 설명된 것처럼 진단 메시지에는 관련된 심각도가 있습니다.

표 6-1 진단 메시지의 심각도

심각도 설명

내부 오류 내부 오류는 컴파일러의 내부 문제를 나타냅니다. xiii페이지의 RealView Compilation Tools에 대한 사용자 의견에 나열된 정보를 공급업체에 제공하십시오.

오류 오류는 컴파일러가 중단되는 문제를 나타냅니다. 이러한 오류에는 명령 행 오류, 내부 오류, include 파일 누락, C 또는 C++ 언어의 구문 또는 의미 규칙 위반이 포함됩니다. 여러 소스 파일을 지정한 경우 오류가 발생한 후에는 소스 파일이 컴파일되지 않습니다.

경고 경고는 코드에서 문제를 나타낼 수 있는 일반적이지 않은 상황을 나타냅니다. 심각도가 오류인 문제가 더 발견되지 않으면 컴파일이 계속되고 개체 코드가 생성됩니다.

주의 주의는 일반적이지만 때로 기존 사용 방식과 다른 C 또는 C++ 사용을 나타냅니다. 주의를 나타내는 진단은 기본적으로 표시되지 않습니다. 심각도가 오류인 문제가 더 발견되지 않으면 컴파일이 계속되고 개체 코드가 생성됩니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 6-3ID090708 Non-Confidential, Unrestricted Access

Page 158: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

진단 메시지

6.3 진단 메시지의 출력 제어

다음 옵션을 사용하여 진단 메시지의 출력을 제어할 수 있습니다.

--no_brief_diagnostics, --brief_diagnostics

더 간단한 형식의 진단 출력이 사용되는 모드를 사용하거나 사용하지 않습니다. 이 옵션을 사용하면 원래 소스 행이 표시되지 않고 오류 메시지 텍스트가 너무 길어 한 행에 맞지 않아도 다음 행으로 이어지지 않습니다. 기본값은 --no_brief_diagnostics입니다.

--diag_style={arm|ide|gnu}

진단 메시지를 표시하는 데 사용되는 스타일을 지정합니다.

--errors=filename

이 옵션은 stderr에서 지정된 오류 파일(filename)로 진단 메시지 출력을 리디렉션합니다. 이 옵션은 파일의 출력 리디렉션이 잘 지원되지 않는 시스템에서 유용합니다.

--remarks 구조체 내의 패딩에 대한 경고 같은 주의 메시지를 생성하도록 컴파일러에 지시할 수 있습니다. 주의는 기본적으로 생성되지 않습니다.

--no_wrap_diagnostics, --wrap_diagnostics

오류 메시지 텍스트가 너무 길어 한 행에 맞지 않는 경우 다음 행으로 이어지는 기능을 사용하거나 사용하지 않습니다.

컴파일러 참조 설명서의 2-2페이지의 명령 행 옵션을 참조하십시오.

6-4 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 159: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

진단 메시지

6.4 진단 메시지 심각도 변경

이러한 옵션을 사용하면 모든 주의 및 경고와 제한된 수의 오류에 해당하는 진단 심각도를 변경할 수 있습니다.

--diag_error=tag[, tag, ...]

지정된 태그가 있는 진단 메시지의 심각도를 오류로 설정합니다.

--diag_remark=tag[, tag, ...]

지정된 태그가 있는 진단 메시지의 심각도를 주의로 설정합니다.

--diag_warning=tag[, tag, ...]

지정된 태그가 있는 진단 메시지의 심각도를 경고로 설정합니다.

이러한 옵션에는 변경할 오류 메시지의 쉼표로 구분된 목록이 필요합니다. 예를 들어 주의는 기본적으로 표시되지 않기 때문에 숫자 #1293이 있는 경고 메시지의 심각도를 주의로 변경할 수 있습니다.

변경하려면 다음 명령을 실행하십시오.

armcc --diag_remark=1293 ...

참고

이 옵션에도 pragma와 동등한 기능이 있습니다. 자세한 내용은 4-14페이지의 Pragma를 참조하십시오.

다음 진단 메시지는 변경할 수 있습니다.

• 숫자 형식 #nnnn-D가 있는 메시지

• 숫자 형식 CnnnnW가 있는 경고 메시지

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 6-5ID090708 Non-Confidential, Unrestricted Access

Page 160: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

진단 메시지

6.5 진단 메시지 표시 안 함

지정된 태그가 있는 모든 진단 메시지를 표시하지 않으려면 --diag_suppress=tag[, tag, ...] 옵션을 사용하십시오.

추가 참고:

• 4-14페이지의 Pragma

• 컴파일러 참조 설명서의 2-49페이지의 --diag_suppress=tag[,tag,...]

6-6 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 161: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

진단 메시지

6.6 진단 메시지의 접두사 문자

표 6-2에 설명된 것처럼 RVCT 도구는 진단 메시지에 자동으로 식별 문자를 삽입합니다. 이러한 접두사 문자를 사용하면 RVCT 도구에서 겹치는 메시지 범위를 사용할 수 있습니다.

다음 규칙이 적용됩니다.

• 모든 RVCT 도구는 접두사 없는 메시지 번호를 처리합니다.

• 접두사가 있는 메시지 번호는 일치하는 접두사가 있는 도구에서만 적용됩니다.

• 일치하지 않는 접두사가 있는 메시지는 도구로 처리되지 않습니다.

따라서 컴파일러 접두사 C는--diag_error, --diag_remark 및 --diag_warning과 함께 사용하거나 메시지를 표시하지 않을 때 사용할 수 있습니다. 예를 들면 다음과 같습니다.

armcc --diag_suppress=C1287,C3017 ...

이 접두사 문자를 사용하여 컴파일러에서 다른 도구로 전달되는 옵션을 제어할 수 있습니다. 예를 들어 접두사 문자 L을 포함하여 링커 메시지 번호를 지정합니다.

표 6-2 진단 메시지 식별

접두사 문자 RVCT 도구

C armcc

A armasm

L armlink 또는 armar

Q fromelf

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 6-7ID090708 Non-Confidential, Unrestricted Access

Page 162: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

진단 메시지

6.7 -W 옵션을 지정하여 경고 메시지를 표시하지 않음

-W 옵션을 지정하면 모든 경고가 표시되지 않습니다.

6-8 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 163: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

진단 메시지

6.8 상태 코드 종료 및 종료 메시지

컴파일하는 동안 컴파일러에서 경고나 오류를 검색하면 컴파일러에서 stderr에 메시지를 작성합니다. 메시지 끝에 다음 형식의 각 메시지 유형 총 수를 제공하는 요약 메시지가 표시됩니다.

filename: n warnings, n errors

여기서 n은 검색된 경고 또는 오류 수를 나타냅니다.

참고

설명은 기본적으로 표시되지 않습니다. 주의를 표시하려면 --remarks 컴파일러 옵션을 사용하십시오. 주의 메시지만 생성된 경우에는 요약 메시지가 표시되지 않습니다.

이 단원에는 다음과 같은 내용도 포함되어 있습니다.

• 신호에 응답

• 상태 종료

6.8.1 신호에 응답

신호 SIGINT(^C와 같은 사용자 인터럽트에 의해 발생) 및 SIGTERM(UNIX kill 명령에 의해 발생)은 컴파일러에 의해 트래핑되고 비정상 종료를 발생시킵니다.

6.8.2 상태 종료

완료할 때 오류가 있는 경우에는 컴파일러에서 0보다 큰 값을 반환합니다. 오류가 검색되지 않으면 값으로 0이 반환됩니다.

컴파일러에서 다양한 수준의 진단 메시지를 처리하는 방법에 대한 자세한 내용은 6-3페이지의 진단 메시지의 심각도를 참조하십시오.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 6-9ID090708 Non-Confidential, Unrestricted Access

Page 164: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

진단 메시지

6.9 데이터 흐름 경고

컴파일러에서 최적화 프로세서의 일부로 데이터 흐름 분석을 수행합니다. 이 정보는 코드에서 잠재적인 문제를 확인하는 데 사용할 수 있습니다. 예를 들어 초기화되지 않은 변수의 사용에 대해 경고를 발생합니다.

데이터 흐름 분석은 스택에 있는 메모리, 변수 또는 구조체에 있는 전역 변수가 아니라 프로세서 레지스터에 있는 지역 변수에 대해서만 경고를 생성할 수 있습니다.

다음 사항에 유의하십시오.

• 데이터 흐름 경고는 기본적으로 표시됩니다. RVCT v2.0 이전에서는 -fa 옵션을 지정한 경우에만 데이터 흐름 경고가 발생합니다.

• -O0에는 -fa 옵션이 지정된 경우에도 데이터 흐름 분석을 사용할 수 없습니다.

이 분석의 결과는 사용되는 최적화에 따라 달라집니다. 즉, 높은 최적화 수준을 사용하는 경우 낮은 수준에서는 표시되지 않는 경고가 생성됩니다. 예를 들어 다음과 같은 소스 코드를 사용하면 컴파일러에서 -O2에 C3017W: i may be used before being set 경고가 생성됩니다.

int f(void){

int i;return i++;

}

데이터 흐름 분석은 오류 코드를 안정적으로 확인할 수 없으며 컴파일러에서 발생한 C3017W 경고는 가능한 문제의 표시로만 사용됩니다. 코드를 완전히 분석하는 경우 --diag_suppress=C3017을 지정하여 이 경고가 표시되지 않도록 설정한 다음 Lint와 같은 타사 분석 도구를 사용하십시오.

6-10 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 165: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

7장 인라인 및 임베디드 어셈블러 사용

이 장에서는 ARM 컴파일러 armcc의 최적화 기능이 있는 인라인 어셈블러와 최적화 기능이 없는 임베디드 어셈블러에 대해 설명합니다. 이 장은 다음 단원으로 구성되어 있습니다.

• 7-2페이지의 인라인 어셈블러

• 7-19페이지의 임베디드 어셈블러

• 7-29페이지의 sp, lr 또는 pc에 액세스하는 레거시 인라인 어셈블러

• 7-31페이지의 인라인 어셈블리 코드와 임베디드 어셈블리 코드의 차이점

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-1ID090708 Non-Confidential, Unrestricted Access

Page 166: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

7.1 인라인 어셈블러

ARM 컴파일러는 사용자가 최적화된 어셈블리 언어 루틴을 작성하고 C 또는 C++에서 사용할 수 없는 타겟 프로세서의 기능에 액세스할 수 있는 인라인 어셈블러를 제공합니다.

이 단원에는 다음 소단원이 포함되어 있습니다.

• 인라인 어셈블러 지원

• 7-3페이지의 인라인 어셈블러 구문

• 7-6페이지의 인라인 어셈블리 연산의 제한

• 7-9페이지의 가상 레지스터

• 7-10페이지의 상수

• 7-10페이지의 명령어 확장

• 7-11페이지의 조건 플래그

• 7-11페이지의 피연산자

• 7-13페이지의 함수 호출 및 분기

• 7-16페이지의 레이블

• 7-16페이지의 이전 버전 ARM C/C++ 컴파일러와의 차이

추가 참고:

• C 및 C++ 코드에서 인라인 어셈블러를 사용하는 방법 및 어셈블리 언어의 제한에 대한 자세한 내용은 개발자 설명서의 4장 C, C++ 및 어셈블리 언어 조합을 참조하십시오.

• ARM 프로세서용 어셈블리 언어 작성에 대한 자세한 내용은 어셈블러 설명서를 참조하십시오.

7.1.1 인라인 어셈블러 지원

인라인 어셈블러는 ARM 어셈블리 언어만 지원하고 다음 언어는 지원하지 않습니다.

• Thumb 어셈블리 언어

• Thumb-2 어셈블리 언어

• ARMv7 명령어

• VFP 명령어

• NEON 명령어

임베디드 어셈블러를 사용하면 Thumb 및 Thumb-2를 지원할 수 있습니다.

7-2 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 167: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

인라인 어셈블러는 ARMv6 SIMD의 모든 명령어를 비롯하여 대부분의 ARMv6 명령어를 지원합니다. 인라인 어셈블러에서 지원하지 않는 ARMv6 명령어는 SETEND 및 일부 시스템 확장입니다.

인라인 어셈블러는 일반 보조 프로세서 명령어를 비롯하여 ARMv5 명령어 세트 대부분을 지원합니다. 인라인 어셈블러에서 지원하지 않는 ARMv5 명령어는 BX, BLX 및 BXJ입니다.

7.1.2 인라인 어셈블러 구문

ARM 컴파일러는 asm 키워드(C++) 또는 __asm 키워드(C 및 C++)에서 도입된 확장 인라인 어셈블러 구문을 지원합니다. 이러한 키워드에 대한 구문은 다음 단원에서 설명합니다.

• __asm 키워드를 사용하는 인라인 어셈블리

• 7-4페이지의 asm 키워드를 사용하는 인라인 어셈블리

• 7-4페이지의 __asm 및 asm 사용 규칙

문이 필요한 모든 위치에 asm 또는 __asm 문을 사용할 수 있습니다.

__asm 키워드를 사용하는 인라인 어셈블리

인라인 어셈블러는 어셈블러 지정자를 사용하여 호출되며 그 뒤에 괄호로 묶인 어셈블러 명령어 목록이 옵니다. 다음 포맷을 사용하여 인라인 어셈블러 코드를 지정할 수 있습니다.

• 단일 행 작성 예

__asm("instruction[;instruction]"); // Must be a single string__asm{instruction[;instruction]}

주석을 포함할 수 없습니다.

• 다중 행 작성 예

__asm{ ... instruction ...}

인라인 어셈블리 언어 블록 어디에나 C 또는 C++ 주석을 사용할 수 있습니다.

7-4페이지의 __asm 및 asm 사용 규칙도 참조하십시오.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-3ID090708 Non-Confidential, Unrestricted Access

Page 168: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

asm 키워드를 사용하는 인라인 어셈블리

C++를 컴파일할 때 ARM 컴파일러는 ISO C++ 표준에서 제안한 asm 구문을 지원합니다. 다음 포맷을 사용하여 인라인 어셈블러 코드를 지정할 수 있습니다.

• 단일 행 작성 예

asm("instruction[;instruction]"); // Must be a single stringasm{instruction[;instruction]}

주석을 포함할 수 없습니다.

• 다중 행 작성 예

asm{ ... instruction ...}

인라인 어셈블리 언어 블록 어느 곳에나 C 또는 C++ 주석을 사용할 수 있습니다.

__asm 및 asm 사용 규칙

__asm 및 asm 키워드를 사용할 때는 다음 규칙을 따르십시오.

• 한 행에 여러 명령어를 입력하는 경우 각 명령어를 세미콜론(;)으로 구분해야 합니다. 큰따옴표(")를 사용하는 경우 큰따옴표 한 쌍 안에 모든 명령어가 포함되어야 합니다.

• 명령어에 두 행 이상이 필요한 경우 백슬래시 문자(\)를 사용하여 행 연결을 지정해야 합니다.

• 다중 행 포맷의 경우 인라인 어셈블리 언어 블록 어느 곳에나 C 또는 C++ 주석을 사용할 수 있습니다. 그러나 여러 명령어가 포함된 행에는 주석을 넣을 수 없습니다.

• 어셈블리 언어에서는 콤마(,)가 구분 기호로 사용되므로 콤마 연산자가 있는 C 식은 괄호로 묶어 구분해야 합니다.

__asm{

ADD x, y, (f(), z)}

7-4 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 169: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

• asm 문은 C++ 함수 안에 있어야 합니다. C++ 문이 필요한 모든 위치에 asm 문을 사용할 수 있습니다.

• 인라인 어셈블러의 레지스터 이름은 C 또는 C++ 변수로 처리됩니다. 이러한 레지스터는 이름이 같은 물리 레지스터와 관련이 없을 수도 있습니다(7-9페이지의 가상 레지스터 참조). 레지스터를 C 또는 C++ 변수로 선언하지 않으면 컴파일러에서 경고를 생성합니다.

• 인라인 어셈블러에서 레지스터를 저장하거나 복원하지 마십시오. 이 작업은 컴파일러에서 수행합니다. 또한 인라인 어셈블러에서는 물리 레지스터에 직접 액세스할 수 없습니다. 자세한 내용은 7-9페이지의 가상 레지스터를 참조하십시오.

CPSR 및 SPSR 이외의 레지스터를 작성하지 않은 채 읽으면 오류 메시지가 표시됩니다. 예를 들어 다음과 같습니다.

int f(int x){ __asm { STMFD sp!, {r0} // save r0 - illegal: read before write ADD r0, x, 1 EOR x, r0, x LDMFD sp!, {r0} // restore r0 - not needed. } return x;}

이 함수는 다음과 같이 작성해야 합니다.

int f(int x){ int r0; __asm { ADD r0, x, 1 EOR x, r0, x } return x;}

자세한 내용은 7-6페이지의 인라인 어셈블리 연산의 제한을 참조하십시오.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-5ID090708 Non-Confidential, Unrestricted Access

Page 170: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

7.1.3 인라인 어셈블리 연산의 제한

인라인 어셈블리 코드에서 실행할 수 있는 연산에는 여러 가지 제한이 있습니다. 이러한 제한은 안전 조치일 뿐 아니라 컴파일된 C 및 C++ 코드의 가정이 어셈블된 어셈블리 코드에서 위반되지 않도록 합니다.

기타 제한

인라인 어셈블러에는 다음 제한이 있습니다.

• 인라인 어셈블러는 상위 수준의 어셈블러이며 인라인 어셈블러에서 생성하는 코드는 사용자가 작성하는 코드와 정확히 일치하지 않을 수 있습니다. 컴파일러에서 생성하는 코드보다 효과적인 코드를 생성하려면 인라인 어셈블러를 사용하지 말고 임베디드 어셈블러 또는 ARM 어셈블러 armasm을 사용하십시오.

• 분기 및 PC에 작성 등 ARM 어셈블러 armasm에서 사용할 수 있는 일부 하위 수준의 기능은 지원되지 않습니다.

• 레이블 식은 지원되지 않습니다.

• 점 표시(.) 또는 {PC}를 사용하여 현재 명령어의 주소를 가져올 수 없습니다.

• & 연산자를 사용하여 16진수 상수를 표시할 수 없습니다. 대신 0x 접두사를 사용하십시오. 예를 들어 다음과 같습니다.

__asm { AND x, y, 0xF00 }

• 인라인 어셈블리 언어에서는 8비트 상수의 실제 회전을 지정하는 표시를 사용할 수 없습니다. 즉, 8비트 시프트 상수가 사용된 경우 NZCV 플래그가 업데이트되면 C 플래그가 손상된 것으로 간주해야 합니다.

• 스택을 수정할 수 없습니다. 컴파일러가 작업 중인 모든 레지스터를 필요에 따라 자동으로 스택하고 복원하므로 수정할 필요가 없습니다. 컴파일러에서는 명시적으로 작업 레지스터를 스택하고 복원할 수 없습니다.

레지스터

r0-r3, sp, lr 등의 레지스터와 CPSR의 NZCV 플래그는 신중하게 사용해야 합니다. C 또는 C++ 식을 사용하는 경우 이들은 임시 레지스터로 사용되며 NZCV 플래그는 식을 평가할 때 컴파일러에 의해 손상될 수 있습니다. 자세한 내용은 7-9페이지의 가상 레지스터를 참조하십시오.

7-6 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 171: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

물리 레지스터에 직접 액세스할 수 없으므로 pc, lr 및 sp 레지스터는 인라인 어셈블리 코드를 사용하여 명시적으로 읽거나 수정할 수 없습니다. 그러나 컴파일러 참조 설명서에서 설명하는 다음 내장 함수를 사용하여 이러한 레지스터에 액세스할 수 있습니다.

• 4-79페이지의 __current_pc

• 4-80페이지의 __current_sp

• 4-97페이지의 __return_address

프로세서 모드

프로세서 모드를 변경하거나 보조 프로세서의 상태를 변경할 수 있지만 컴파일러에서는 이러한 변경 사항을 인식하지 않습니다. 프로세서 모드를 변경한 경우 C 또는 C++ 식을 사용하려면 원래 모드로 다시 변경해야 합니다. 그렇지 않으면 컴파일러가 새 프로세서 모드의 레지스터를 손상시킵니다.

마찬가지로 부동 소수점 명령어를 실행하여 부동 소수점 보조 프로세서의 상태를 변경하는 경우, 부동 소수점 식을 사용하려면 원래 상태로 복원해야 합니다.

Thumb 명령어 세트

Thumb 상태에 대해 C 또는 C++를 컴파일할 때 인라인 어셈블러를 사용할 수 없으며 인라인 어셈블러는 Thumb 명령어를 어셈블하지 않습니다. 대신 컴파일러가 자동으로 ARM 상태로 전환합니다.

Thumb에 대해 컴파일할 코드가 포함된 소스 파일에 인라인 어셈블리를 포함하려면 인라인 어셈블러 코드가 있는 함수를 #pragma arm과 #pragma thumb 문 사이에 포함하십시오. 예를 들어 다음과 같습니다.

... // Thumb code#pragma arm // ARM code. Switch code generation to the ARM instruction set so

// that the inline assembler is available.

int add(int i, int j){

int res;__asm{

ADD res, i, j // add here}return res;

}#pragma thumb // Thumb code. Switch back to the Thumb instruction set.

// The inline assembler is no longer available.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-7ID090708 Non-Confidential, Unrestricted Access

Page 172: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

또한 --apcs /interwork 컴파일러 옵션을 사용하여 코드를 컴파일해야 합니다.

참조:

• 2-26페이지의 인터워킹 한정자

• 컴파일러 참조 설명서의 4-58페이지의 Pragma

VFP 보조 프로세서

인라인 어셈블러에서는 VFP 명령어를 직접 지원하지 않지만 일반 보조 프로세서 명령어를 사용하여 VFP 명령어를 지정할 수 있습니다.

인라인 어셈블리 코드는 VFP 벡터 모드를 변경하는 데 사용할 수 없습니다. 인라인 어셈블리는 컴파일러에서 생성한 VFP 코드를 사용하여 평가할 수 있는 부동 소수점 피연산자 식을 포함할 수 있습니다. 따라서 컴파일러를 통해서만 VFP의 상태를 수정해야 합니다.

지원되지 않는 명령어

다음 명령어는 인라인 어셈블러에서 지원되지 않습니다.

• BKPT, BX, BXJ 및 BLX 명령어

참고

__breakpoint() 내장 함수를 사용하여 C 및 C++ 코드에 BKPT 명령어를 삽입할 수 있습니다.

• LDR Rn, =expression 의사 명령어. 대신 MOV Rn, expression를 사용하십시오. (이를 통해 리터럴 풀에서 로드를 생성할 수 있습니다.)

• LDRT, LDRBT, STRT 및 STRBT 명령어

• MUL, MLA, UMULL, UMLAL, SMULL 및 SMLAL 플래그 설정 명령어

• MOV 또는 MVN 플래그 설정 명령어(여기서 두 번째 피연산자는 상수임)

• 사용자 모드 LDM 명령어

• ADR 및 ADRL 의사 명령어

컴파일러 참조 설명서의 4-77페이지의 __breakpoint를 참조하십시오.

7-8 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 173: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

7.1.4 가상 레지스터

인라인 어셈블러에서 ARM 프로세서의 물리 레지스터에 직접 액세스할 수 없습니다. 인라인 어셈블러 명령어에서 ARM 레지스터 이름이 피연산자로 사용되는 경우 물리 ARM 레지스터가 아니라 이름이 같은 가상 레지스터에 대한 참조가 됩니다.

컴파일러는 최적화 및 코드 생성 중에 각 가상 레지스터에 물리 레지스터를 적절히 할당합니다. 그러나 어셈블된 코드에 사용된 물리 레지스터는 명령어에 지정된 것과 다를 수 있습니다. 이러한 가상 레지스터는 명시적으로 기본 C 또는 C++ 변수로 정의할 수 있습니다. 가상 레지스터가 정의되지 않으면 컴파일러에서 가상 레지스터에 대한 암시적 정의를 제공합니다.

컴파일러에서 정의한 가상 레지스터에는 함수 지역 범위가 있습니다. 즉, 단일 함수 내에서는 같은 가상 레지스터 이름을 참조하는 여러 개의 asm 문이나 선언이 해당 가상 레지스터에 액세스합니다.

가상 레지스터는 sp(r13), lr(r14) 및 pc(r15) 레지스터에 대해 생성되지 않으며 인라인 어셈블리 코드에서 읽거나 직접 수정할 수 없습니다. 소스 코드를 수정하는 방법에 대한 자세한 내용은 7-29페이지의 sp, lr 또는 pc에 액세스하는 레거시 인라인 어셈블러를 참조하십시오.

가상 PSR(프로세서 상태 레지스터)은 존재하지 않습니다. PSR에 대한 참조는 언제나 물리 PSR에 대한 것입니다.

각 명령어에 사용된 실제 레지스터는 다를 수 있지만 이전에 문서화된 가이드라인을 따르는 기존 인라인 어셈블러 코드는 계속 이전 버전의 컴파일러와 동일한 기능을 수행합니다.

각 가상 레지스터의 초기 값은 예측할 수 없습니다. 가상 레지스터는 먼저 작성한 다음 읽어야 합니다. 변수 r1과 연관된 가상 레지스터를 읽으려고 시도하는 경우와 같이 가상 레지스터를 작성하기 전에 읽으려고 시도하면 컴파일러에서 오류가 생성됩니다.

또한 C 또는 C++ 코드에서 변수 이름을 명시적으로 선언해야 합니다. C 또는 C++ 변수를 명령어 피연산자로 사용하는 것이 좋습니다. 가상 또는 물리 레지스터 이름을 처음 사용하려고 하면 컴파일러에서 경고가 생성됩니다. 이 경고는 각 변환 단위에 대해 한 번만 생성됩니다. 예를 들어 레지스터 r3을 지정하면 경고가 표시됩니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-9ID090708 Non-Confidential, Unrestricted Access

Page 174: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

7.1.5 상수

상수 식 지정자 # 기호는 선택 사항입니다. 이 지정자를 사용하는 경우 그 뒤에 오는 식이 상수여야 합니다.

7.1.6 명령어 확장

인라인 어셈블리 코드의 ARM 명령어는 컴파일된 개체에서 여러 개의 명령어로 확장될 수 있습니다. 확장은 명령어, 명령어에 지정된 피연산자 수 및 각 피연산자의 유형과 값에 따라 달라집니다.

상수를 사용하는 명령어

상수 피연산자가 있는 명령어의 상수는 명령어가 허용한 값으로 제한되지 않습니다. 대신 컴파일러에서 명령어를 동일한 결과를 산출하는 명령어 시퀀스로 변환합니다. 예를 들면 다음과 같습니다.

ADD r0,r0,#1023

이는 다음과 같이 변환될 수 있습니다.

ADD r0,r0,#1024SUB r0,r0,#1

보조 프로세서 명령어를 제외한, 상수 피연산자가 있는 모든 ARM 명령어는 명령어 확장을 지원합니다. 또한 세 번째 피연산자가 상수이면 MUL 명령어를 연속 추가 및 시프트로 확장할 수도 있습니다.

확장된 명령어를 사용하여 CPSR을 업데이트하면 다음과 같은 결과가 나타납니다.

• 산술 명령어가 NZCV 플래그를 올바로 설정합니다.

• 논리 명령어:

— NZ 플래그를 올바로 설정합니다.

— V 플래그를 변경하지 않습니다.

— C 플래그를 손상시킵니다.

명령어 로드 및 저장

LDM, STM, LDRD 및 STRD 명령어는 상응하는 ARM 명령어로 대체될 수 있습니다. 이 경우 ARM 컴파일러는 명령어가 확장될 수 있다는 경고 메시지를 표시합니다.

7-10 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 175: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

인라인 어셈블리 코드는 예상 명령어 수 또는 지정된 각 명령어의 예상 실행 시간에 따라 달라지지 않도록 작성해야 합니다.

일반적으로 LDRD 및 STRD와 같이 연산자 레지스터 쌍에 대한 제한을 적용하는 명령어는 이러한 제한이 없는 동일 기능의 명령어 시퀀스로 대체됩니다. 그러나 이러한 명령어는 LDRD 및 STRD 명령어로 다시 조합될 수 있습니다.

모든 LDM 및 STM 명령어는 같은 결과를 가져오는 LDR 및 STR 명령어의 시퀀스로 확장됩니다. 그러나 그 후 컴파일러가 각각의 명령어를 최적화 도중에 LDM 또는 STM으로 다시 조합할 수 있습니다.

7.1.7 조건 플래그

인라인 어셈블리 명령이 명시적으로 또는 암시적으로 프로세서 조건 플래그의 업데이트를 시도할 수 있습니다. 가상 레지스터 피연산자 또는 단순 피연산자 식(피연산자 참조)만을 포함하는 인라인 어셈블리 명령어에는 예측 가능한 동작이 있습니다. 명시적 또는 암시적 업데이트가 지정된 경우 조건 플래그는 명령어를 통해 설정됩니다. 업데이트가 지정되지 않으면 조건 플래그가 변경되지 않습니다. 명령어 피연산자 중 하나라도 단순 피연산자가 아닌 경우 명령어가 해당 피연산자를 업데이트하지 않으면 조건 플래그가 손상될 수 있습니다. 일반적으로 컴파일러는 조건 플래그의 손상 가능성을 쉽게 진단할 수 없습니다. 그러나 C++ 임시 파일을 생성한 다음 소멸해야 하는 피연산자의 경우 명령어가 조건 플래그를 업데이트하려 할 때 컴파일러에서 경고를 표시합니다. 소멸로 인해 조건 플래그가 손상될 수 있기 때문입니다.

7.1.8 피연산자

피연산자는 다음 유형 중 하나일 수 있습니다.

가상 레지스터

인라인 어셈블리 명령어에 지정된 레지스터는 항상 가상 레지스터를 표시하고 물리 ARM 정수 레지스터는 표시하지 않습니다. 가상 레지스터는 선언할 필요가 없으며 가상 레지스터의 크기는 물리 레지스터와 같습니다. 그러나 어셈블된 코드에 사용된 물리 레지스터는 명령어에 지정된 것과 다를 수 있습니다. 자세한 내용은 7-9페이지의 가상 레지스터를 참조하십시오.

피연산자 식

함수 인수, C 또는 C++ 변수, 그 밖에 기타 C 또는 C++ 식을 인라인 어셈블리 명령어의 레지스터 피연산자로 지정할 수 있습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-11ID090708 Non-Confidential, Unrestricted Access

Page 176: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

ARM 정수 레지스터의 위치에 사용되는 식 유형은 long long을 제외한 정수 유형(즉 char, short, int 또는 long)이나 포인터 유형 중 하나여야 합니다. char 또는 short 유형에서는 부호 확장이 수행되지 않습니다. 이러한 유형에 대해서는 명시적으로 부호 확장을 수행해야 합니다. 컴파일러에서 코드를 추가하여 이러한 식을 평가하고 레지스터에 할당할 수 있습니다.

피연산자가 대상으로 사용될 때 레지스터 수정이 이루어지는 피연산자로 식이 사용된다면 그 식은 반드시 수정 가능한 Ivalue여야 합니다. 기본 레지스터 업데이트가 있는 기본 레지스터 또는 대상 레지스터가 그 예입니다.

피연산자 식이 둘 이상인 명령어의 경우 피연산자 식을 평가하는 순서가 지정되지 않습니다.

조건 명령어의 피연산자 식은 명령어의 조건이 충족되는 경우에만 평가됩니다.

인라인 어셈블러 피연산자로 쓰이는 C 또는 C++ 식을 사용할 경우 명령어가 여러 명령어로 확장되는 결과를 가져올 수 있습니다. 식의 값이 ARM Architecture Reference Manual의 명령어 피연산자에 대해 설정된 제한을 충족하지 않는 경우에 이러한 결과가 발생합니다.

피연산자로 사용되는 식에서 소멸될 임시 파일이 생성되면 그 파일은 인라인 어셈블리 명령어가 실행된 후에 소멸됩니다. 이것은 임시 파일의 소멸에 대한 C++ 규칙과 비슷합니다.

단순 피연산자 식은 다음 중 하나입니다.

• 변수 값

• 변수의 주소

• 포인터 변수 역참조

• 컴파일시간 상수

다음 중 하나라도 포함하는 모든 식은 단순 피연산자 식이 아닙니다.

• 나누기에 대한 호출과 같은 암시적 함수 호출 또는 명시적 함수 호출

• C++ 임시 파일의 생성

• 산술 또는 논리 피연산자

레지스터 목록

레지스터 목록에는 최대 16개의 피연산자가 포함될 수 있습니다. 이러한 피연산자로는 가상 레지스터 또는 식 레지스터 피연산자가 있습니다.

7-12 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 177: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

레지스터 목록에서 가상 레지스터 및 피연산자 식이 지정되는 순서는 중요합니다. 레지스터 목록 피연산자는 왼쪽에서 오른쪽 순서로 읽거나 작성합니다. 첫 번째 피연산자는 최하위 주소를 사용하고 그 다음 피연산자는 이전 주소에 4를 더해 만든 주소를 사용합니다. 이 새로운 동작은 최하위 숫자가 지정된 물리 레지스터가 항상 최하위 메모리 주소에 저장되는 LDM 또는 STM 명령어의 일반적인 연산과 대비됩니다. 동작의 이러한 차이점은 레지스터 가상화의 결과입니다.

피연산자 식이나 가상 레지스터는 레지스터 목록에 여러 번 표시될 수 있으며 지정할 때마다 사용됩니다.

지정하면 기본 레지스터가 업데이트됩니다. 업데이트하면 메모리 로드 연산 도중에 기본 레지스터로 로드된 값을 덮어씁니다.

레지스터 목록 뒤에 ^ 기호를 지정하여 권한 모드일 때 사용자 모드 레지스터에서 연산하는 기능은 인라인 어셈블러에서 지원되지 않습니다.

중간 피연산자

정수 유형의 C 또는 C++ 상수 식이 인라인 어셈블리 명령어의 중간 값으로 사용될 수 있습니다.

중간 시프트를 지정하기 위해 사용하는 상수 식에는 시프트 연산에 적합하도록 ARM 아키텍처 참조 문서에 정의된 범위 안의 값이 있어야 합니다.

메모리 또는 보조 프로세서 데이터 전송 명령어에 대한 중간 오프셋을 지정하기 위해 사용하는 상수 식에는 적절하게 정렬된 값이 있어야 합니다.

7.1.9 함수 호출 및 분기

인라인 어셈블러의 BL 및 SVC 명령어를 사용하면 기본 명령어 필드 뒤에 세 가지 선택 목록을 지정할 수 있습니다. 이러한 명령어는 다음과 같은 형태로 되어 있습니다.

SVC{cond} svc_num, {input_param_list}, {output_value_list}, {corrupt_reg_list}BL{cond} function, {input_param_list}, {output_value_list}, {corrupt_reg_list}

참고

SVC 명령어의 이전 이름은 SWI였습니다. 인라인 어셈블러에서는 SWI를 SVC 대신 계속 사용할 수 있습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-13ID090708 Non-Confidential, Unrestricted Access

Page 178: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

다음은 목록에 대해 설명하는 단원입니다.

• 목록이 지정되지 않은 경우

• 입력 매개변수 목록

• 7-15페이지의 출력 값 목록

• 7-15페이지의 손상 레지스터 목록

참고

• BX, BLX 및 BXJ 명령어는 인라인 어셈블러에서 지원되지 않습니다.

• lr, sp 또는 pc 레지스터는 어떤 입력, 출력 또는 손상 레지스터 목록에도 지정할 수 없습니다.

• sp 레지스터는 어떤 SVC 명령어 또는 함수 호출로도 변경하면 안 됩니다.

목록이 지정되지 않은 경우

목록을 지정하지 않으면 다음과 결과가 나타납니다.

• r0-r3이 입력 매개변수로 사용됩니다.

• r0이 출력 값으로 사용됩니다.

• r12 및 r14가 손상될 수 있습니다

입력 매개변수 목록

이 목록에서는 함수 호출이나 SVC 명령어에 대한 입력 매개변수가 되는 식 또는 변수를 지정하며 또한 이를 포함하는 물리 레지스터를 지정합니다. 식이나 변수는 물리 레지스터에 대한 할당 또는 물리 레지스터 이름으로 명시됩니다. 단일 목록에 두 유형의 입력 레지스터가 모두 명시될 수 있습니다.

인라인 어셈블러는 BL 또는 SVC 명령어를 입력하기 전에 지정된 물리 레지스터에 올바른 값이 있는지 확인합니다. 할당 없이 지정된 물리 레지스터 이름은 같은 이름의 가상 레지스터에 있는 값이 해당 물리 레지스터에 있는지 확인합니다. 이렇게 하면 기존 인라인 어셈블러 코드와의 역방향 호환성이 보장됩니다.

다음 명령어를 예로 들 수 있습니다.

BL foo, { r0=expression1, r1=expression2, r2 }

7-14 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 179: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

이 명령어는 다음 의사 코드를 생성합니다.

MOV (physical) r0, expression1MOV (physical) r1, expression2MOV (physical) r2, (virtual) r2BL foo

출력 값 목록

이 목록은 BL 또는 SVC의 출력 값이 있는 물리 레지스터 및 이러한 레지스터의 저장 위치를 지정합니다. 출력 값은 단일 물리 레지스터 이름으로 지정되거나 물리 레지스터로부터 수정 가능한 lvalue 식에 이르는 할당으로 지정됩니다.

인라인 어셈블러는 지정 물리 레지스터에서 값을 가져와 지정된 식에 할당합니다. 할당 없이 지정된 물리 레지스터 이름은 같은 이름의 가상 레지스터를 물리 레지스터의 값으로 업데이트합니다.

다음 명령어를 예로 들 수 있습니다.

BL foo, { }, { result1=r0, r1 }

이 명령어는 다음 의사 코드를 생성합니다.

BL fooMOV result1, (physical) r0MOV (virtual) r1, (physical) r1

손상 레지스터 목록

이 목록은 호출된 함수에 의해 손상된 물리 레지스터를 명시합니다. 호출된 함수가 조건 플래그를 수정하면 손상 레지스터 목록에서 PSR을 지정해야 합니다.

BL 및 SVC 명령어는 항상 lr을 손상시킵니다.

BL 및 SVC에 대해 이 목록을 생략하면 레지스터 r0-r3, pc, lr 및 PSR이 손상됩니다.

분기 명령어 B는 단일 C 또는 C++ 함수 내에 있는 레이블로 이동하는 데에만 사용해야 합니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-15ID090708 Non-Confidential, Unrestricted Access

Page 180: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

7.1.10 레이블

인라인 어셈블리 코드에 정의된 레이블은 분기 또는 C와 C++ goto 문에 대한 타겟으로 사용할 수 있습니다. C 및 C++에 정의된 레이블은 인라인 어셈블리 코드의 분기 명령어를 통해 타겟으로 사용할 수 있습니다. 사용 형식은 다음과 같습니다.

BL{cond} label

7.1.11 이전 버전 ARM C/C++ 컴파일러와의 차이

ARM 컴파일러의 인라인 어셈블러와 이전 버전 ARM C 및 C++ 컴파일러의 인라인 어셈블러 사이에는 상당한 차이점이 있습니다. 이 단원에서는 주요 차이점을 위주로 설명합니다. 인라인 어셈블러에 대해 기존 어셈블리 코드를 사용하는 방법에 대한 자세한 내용은 RealView Compilation Tools 개발자 설명서를 참조하십시오.

ARMv6 명령어

인라인 어셈블러는 모든 ARMv6 명령어 중 오직 ARMv6 미디어 명령어만 지원합니다.

가상 레지스터

컴파일러에 대한 인라인 어셈블리 코드는 항상 가상 레지스터를 지정합니다. 컴파일러는 코드를 생성하는 동안 각 명령어에 사용될 물리 레지스터를 선택하고 어셈블리 코드 및 주위의 C 또는 C++ 코드를 완전히 최적화합니다.

pc(r15), lr(r14) 및 sp(r13) 레지스터에는 절대 액세스할 수 없습니다. 이러한 레지스터에 액세스하면 오류 메시지가 생성됩니다.

가상 레지스터의 초기 값이 정의되지 않았습니다. 따라서 먼저 가상 레지스터를 작성한 후에 읽어야 합니다. 가상 레지스터를 작성하기 전에 읽으려고 시도하면 컴파일러에서 경고합니다. 예를 들어 컴파일러는 인라인 어셈블리 코드의 시작 부분에서 물리 레지스터의 특정 값에 의존하는 레거시 코드에 대해서도 이러한 경고를 생성합니다. 예를 들면 다음과 같습니다.

int add(int i, int j){ int res; __asm

{ ADD res, r0, r1 // relies on i passed in r0 and j passed in r1

7-16 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 181: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

} return res;}

이 코드는 경고 및 오류 메시지를 생성합니다.

이 오류는 가상 레지스터 r0 및 r1을 작성하기 전에 읽기 때문에 생성됩니다. 이 경고는 r0 및 r1을 C 또는 C++ 변수로 정의해야 하므로 생성됩니다. 올바른 코드는 다음과 같습니다.

int add(int i, int j){ int res; __asm

{ ADD res, i, j } return res;}

명령어 확장

컴파일러의 인라인 어셈블러는 명령어 LDM, STM, LDRD 및 STRD를 동일한 기능을 수행하는 단일 레지스터 메모리 연산 시퀀스로 확장합니다.

컴파일러는 단일 레지스터 메모리 연산 명령어 시퀀스를 다시 다중 레지스터 메모리 연산으로 최적화할 수 있습니다.

레지스터 목록

LDM 또는 STM 명령어에 대한 레지스터 목록에서 피연산자의 순서는 중요합니다. 피연산자는 정해진 순서대로 사용됩니다. 즉, 왼쪽에서 오른쪽의 순서대로 첫 번째 피연산자는 생성된 최하위 메모리 주소를 참조합니다. 이는 언제나 가장 작은 숫자의 레지스터가 명령어가 생성한 최하위 메모리 주소를 참조하던 이전 컴파일러의 동작과 반대입니다.

이러한 변화는 레지스터 목록의 피연산자 식을 가상 레지스터와 함께 사용할 수 있게 되어 발생한 것입니다. 컴파일러는 가상 레지스터만을 포함한 레지스터 목록을 발견하면 경고 메시지를 생성합니다. 여기서 새로 지정된 순서의 결과는 이전 ARM C 및 C++ 컴파일러에서의 결과와 다릅니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-17ID090708 Non-Confidential, Unrestricted Access

Page 182: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

Thumb 명령어

컴파일러의 인라인 어셈블러는 Thumb � 명령어 세트를 지원하지 않습니다. #pragma arm 및 #pragma thumb pragmas를 사용하지 않는 한 Thumb 명령어를 어셈블하지 않으며 Thumb 상태에 대한 C 또는 C++를 컴파일할 때에도 전혀 사용할 수 없습니다(7-7페이지의 Thumb 명령어 세트 참조).

7-18 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 183: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

7.2 임베디드 어셈블러

ARM 컴파일러를 사용하면 하나 이상의 C 또는 C++ 함수 정의에 행 외부 어셈블리 코드를 포함할 수 있습니다. 임베디드 어셈블러를 통해 타겟 프로세서에 낮은 수준으로 제한 없이 액세스할 수 있고, C 및 C++ 사전 처리기 지시어를 사용할 수 있으며, 손쉽게 액세스하여 구성원 오프셋을 구성할 수 있습니다.

ARM 프로세서용 어셈블리 언어 작성에 대한 자세한 내용은 어셈블러 설명서를 참조하십시오.

7.2.1 임베디드 어셈블러 구문

임베디드 어셈블리 함수 정의는__asm(C 및 C++) 또는 asm(C++) 함수 한정자로 표시되며 다음 함수에서 사용할 수 있습니다.

• 구성원 함수

• 비구성원 함수

• 템플릿 함수

• 템플릿 클래스 구성원 함수

__asm 또는 asm으로 선언된 함수는 인수를 포함할 수 있으며 유형을 반환합니다. 이러한 함수는 기본 C 및 C++ 함수와 같은 방식으로 C 및 C++에서 호출됩니다. 임베디드 어셈블리 함수의 구문은 다음과 같습니다.

__asm return-type function-name(parameter-list){

// ARM/Thumb/Thumb-2 assembler codeinstruction[;instruction] ... instruction

}

임베디드 어셈블러(ARM 또는 Thumb)의 초기 상태는 명령 행에 지정된 대로 컴파일러의 초기 상태에 따라 결정됩니다. 이는 다음과 같은 의미입니다.

• 컴파일러가 ARM 상태에서 시작되면 임베디드 어셈블러가 --arm을 사용합니다.

• 컴파일러가 Thumb 상태에서 시작되면 임베디드 어셈블러가 --thumb을 사용합니다.

각 함수가 시작될 때의 임베디드 어셈블러 상태가 이제 컴파일러 호출을 통해 설정됩니다. 이는 #pragma arm 및 #pragma thumb pragmas에 의해 수정된 것입니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-19ID090708 Non-Confidential, Unrestricted Access

Page 184: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

임베디드 어셈블러 함수에서 명시적 ARM, THUMB 또는 CODE16 지시어를 사용하여 함수 내에서 임베디드 어셈블러의 상태를 변경할 수 있습니다. __asm 함수에 포함된 이러한 지시어는 이후 __asm 함수의 ARM 또는 Thumb 상태에 영향을 주지 않습니다.

Thumb-2 사용 가능 프로세서에 대해 컴파일하는 경우 Thumb 상태일 때 Thumb-2 명령어를 사용할 수 있습니다.

참고

인수 이름이 매개변수 목록에는 허용되지만 임베디드 어셈블리 함수의 본문에는 사용할 수 없습니다. 예를 들어 다음 함수는 함수 본문에 정수 i를 사용하지만 어셈블리에서는 이 정수가 유효하지 않습니다.

__asm int f(int i){ ADD i, i, #1 // error}

예를 들어 i 대신 r0을 사용할 수 있습니다.

C 및 C++ 소스에서 사용되는 임베디드 어셈블러에 대한 자세한 내용은 개발자 설명서에서 C, C++ 및 어셈블리 언어의 조합에 관해 설명하는 장을 참조하십시오.

임베디드 어셈블러 예제

예제 7-1에서는 문자열 복사 루틴을 어셈블러 루틴처럼 사용하는 방법을 보여 줍니다.

예제 7-1 임베디드 어셈블리를 사용하여 문자열 복사

#include <stdio.h>__asm void my_strcpy(const char *src, char *dst){loop LDRB r2, [r0], #1 STRB r2, [r1], #1 CMP r2, #0 BNE loop BX lr}int main(void){

7-20 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 185: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

const char *a = "Hello world!"; char b[20]; my_strcpy (a, b); printf("Original string: '%s'\n", a); printf("Copied string: '%s'\n", b);

return 0;}

7.2.2 임베디드 어셈블리 연산의 제한

다음 제한이 임베디드 어셈블리 함수에 적용됩니다.

• 사전 처리 후에 __asm 함수에는 다음 식별자(7-25페이지의 관련된 기본 클래스에 대한 키워드 및 7-25페이지의 구성원 함수 클래스에 대한 키워드 참조)를 제외한 어셈블리 코드만 포함될 수 있습니다.

__cpp(expr)__offsetof_base(D, B)__mcall_is_virtual(D, f)__mcall_is_in_vbase(D, f)__mcall_offsetof_base(D, f)__mcall_this_offset(D, f)__vcall_offsetof_vfunc(D, f)

• __asm 함수에 대한 컴파일러에서 반환 명령어를 생성하지 않습니다. __asm 함수에서 돌아오려면 어셈블리 코드에서 함수의 본문에 반환 명령어를 포함해야 합니다.

참고

임베디드 어셈블러는 정의한 순서대로 __asm 함수를 내보내므로 이렇게 하면 다음 함수로 잘못 넘어갈 수 있습니다. 그러나 인라인 함수와 템플릿 함수는 다르게 동작합니다(7-22페이지의 임베디드 어셈블리 함수의 생성 참조).

• __asm 함수는 적용하는 AAPCS 규칙을 변경하지 않습니다. 즉, __asm 함수가 사용할 수 있는 어셈블리 코드(예: 변경 상태)에 대한 제한이 없더라도 __asm 함수와 기본 C 또는 C++ 함수 간의 모든 호출은 AAPCS를 따라야 합니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-21ID090708 Non-Confidential, Unrestricted Access

Page 186: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

7.2.3 임베디드 어셈블리 식과 C 또는 C++ 식의 차이점

임베디드 어셈블리와 C 또는 C++는 다음과 같은 점이 다릅니다.

• 어셈블러 식은 항상 unsigned입니다. 같은 식이라도 어셈블리와 C 또는 C++는 서로 다른 값을 가질 수 있습니다. 예를 들면 다음과 같습니다.

MOV r0, #(-33554432 / 2) // result is 0x7f000000MOV r0, #__cpp(-33554432 / 2) // result is 0xff000000

• 0이 선행하는 경우에도 어셈블러 번호는 10진수입니다. 예를 들면 다음과 같습니다.

MOV r0, #0700 // decimal 700MOV r0, #__cpp(0700) // octal 0700 == decimal 448

• 어셈블러 연산자 우선순위는 C 및 C++와 다릅니다. 예를 들어 다음과 같습니다.

MOV r0, #(0x23 :AND: 0xf + 1) // ((0x23 & 0xf) + 1) => 4MOV r0, #__cpp(0x23 & 0xf + 1) // (0x23 & (0xf + 1)) => 0

• 어셈블러 문자열은 Null로 끝나지 않습니다.

DCB "Hello world!" // 12 bytes (no trailing null)DCB __cpp("Hello world!") // 13 bytes (trailing null)

참고

어셈블러 규칙은 __cpp 외부에 적용되고 C 또는 C++ 규칙은 __cpp. S 내부에 적용됩니다(7-24페이지의 __cpp 키워드 참조).

7.2.4 임베디드 어셈블리 함수의 생성

변환 단위의 모든 __asm 함수 본문은 마치 단일 파일로 연결된 다음 ARM 어셈블러로 전달되는 것처럼 어셈블됩니다. 템플릿 인스턴스화를 사용하여 생성되는 함수를 제외하면 어셈블러에 전달되는 어셈블리 파일의 __asm 함수 순서는 소스 파일과 같습니다.

참고

이것은 반환 명령어가 생략된 경우 파일에서 첫 번째 함수의 끝에서 나와 다음__asm 함수로 들어가는 방식으로 컨트롤이 한 __asm 함수에서 다른 함수로 넘어갈 수 있음을 의미합니다.

armcc를 호출할 때 어셈블러가 생성한 개체 파일이 단일 개체 파일을 생성하는 부분적 링크를 통해 컴파일러의 개체 파일과 결합됩니다.

7-22 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 187: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

컴파일러는 예제 7-2와 같이 각 __asm 함수에 대해 AREA 지시어를 생성합니다.

예제 7-2 __asm 함수

#include <cstddef>struct X{

int x,y;void addto_y(int);

};__asm void X::addto_y(int){ LDR r2, [r0, #__cpp(offsetof(X, y))] ADD r1, r2, r1 STR r1, [r0, #__cpp(offsetof(X, y))] BX lr}

이 함수에서 컴파일러는 다음을 생성합니다.

AREA ||.emb_text||, CODE, READONLY EXPORT |_ZN1X7addto_yEi|#line num "file"|_ZN1X7addto_yEi| PROC LDR r2, [r0, #4] ADD r1, r2, r1 STR r1, [r0, #4] BX lr ENDP END

offsetof는 cstddef 헤더 파일의 기본 offsetof 매크로이므로 __cpp() 내에서 사용해야 합니다.

일반 __asm 함수는 .emb_text라는 이름으로 ELF 섹션에 배치됩니다. 즉, 임베디드 어셈블리 함수는 인라인되지 않습니다. 그러나 인라인 함수의 행 외부 사본과 암시적으로 인스턴스화된 템플릿 함수는 함수의 이름에서 파생된 이름 및 두 함수의 공통점인 추가 특성을 보유하고 같은 영역에 배치됩니다. 이 작업을 통해 이러한 함수의 특수한 의미가 유지됩니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-23ID090708 Non-Confidential, Unrestricted Access

Page 188: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

참고

인라인 함수의 행 외부 사본과 템플릿 함수 영역의 특수한 이름으로 인해 이 두 함수는 정의의 순서를 따르지 않고 임의 순서대로 놓입니다. 따라서 코드가 인라인 함수 또는 템플릿 함수 외부에서 실행되어 다른 __asm 함수로 건너뛴다고 생각할 수는 없습니다.

7.2.5 __cpp 키워드

__cpp 키워드를 사용하여 어셈블리 코드에서 외부 링크가 있는 데이터 또는 함수의 주소를 비롯하여 C 또는 C++ 컴파일시간 상수 식에 액세스할 수 있습니다. __cpp 내부의 식은 C++ 정적 초기화로 사용하기에 적합한 상수 식이어야 합니다 (ISO/IEC 14882:2003의 3.6.2 Initialization of non-local objects 및 5.19 Constant expressions 참조).

예제 7-3에서는 __cpp(expr) 대신 사용할 수 있는 상수를 보여 줍니다.

예제 7-3 __cpp(expr)

LDR r0, =__cpp(&some_variable)LDR r1, =__cpp(some_function)BL __cpp(some_function)MOV r0, #__cpp(some_constant_expr)

__cpp 식의 이름이 C++ __asm 함수의 문맥에서 참조됩니다. __cpp 식의 결과로 나타나는 모든 이름은 필요에 따라 잘리고 이러한 이름에 대해 생성된 IMPORT 문이 자동으로 포함됩니다.

7.2.6 수동으로 오버로드 해결

예제 7-4에서는 C++ 캐스트를 사용하여 가상이 아닌 함수 호출에 대해 오버로드 해결을 수행하는 방법을 보여 줍니다.

예제 7-4 C++ 캐스트

void g(int);void g(long);struct T{ int mf(int);

7-24 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 189: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

int mf(int,int);};__asm void f(T*, int, int){ BL __cpp(static_cast<int (T::*)(int, int)>(&T::mf)) // calls T::mf(int, int) BL __cpp(static_cast<void (*)(int)>(g)) // calls g(int) BX lr}

7.2.7 관련된 기본 클래스에 대한 키워드

다음 키워드를 사용하면 개체의 시작 부분부터 기본 클래스 하위 개체까지 오프셋을 확인할 수 있습니다.

__offsetof_base(D, B)

B는 D의 모호하지 않으며 가상이 아닌 기본 클래스여야 합니다.

D 개체의 시작부터 여기에 포함된 B 기본 하위 개체의 시작까지 오프셋을 반환합니다. 결과는 0일 수 있습니다. 예제 7-5에서는 static_cast<B*>(p)처럼 구현하기 위해 D* p에 추가해야 하는 오프셋(바이트)을 보여 줍니다.

예제 7-5 static_cast<B*>(p)

__asm B* my_static_base_cast(D* /*p*/){ if __offsetof_base(D, B) <> 0 // optimize zero offset case ADD r0, r0, #__offsetof_base(D, B) endif BX lr}

이러한 키워드는 어셈블러 소스에서 정수 또는 논리 상수로 변환되며, __asm 함수에서만 사용할 수 있고 __cpp 식에는 사용할 수 없습니다.

7.2.8 구성원 함수 클래스에 대한 키워드

다음 키워드는 __asm__asm 함수에서 가상 및 가상이 아닌 구성원 함수를 쉽게 호출할 수 있도록 도와 줍니다. __mcall로 시작하는 키워드는 가상 함수와 가상이 아닌 함수 모두에 사용할 수 있습니다. __vcall로 시작하는 키워드는 가상 함수에서만 사용할 수 있습니다. 키워드가 특별히 정적 구성원 함수의 호출을 돕지는 않습니다.

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-25ID090708 Non-Confidential, Unrestricted Access

Page 190: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

이러한 키워드의 사용 방법을 보여 주는 예는 7-27페이지의 비정적 구성원 함수 호출을 참조하십시오.

__mcall_is_virtual(D, f)

f가 D 또는 D 기본 클래스의 가상 구성원 함수이면 {TRUE}를 반환하고, 그렇지 않으면 {FALSE}를 반환합니다. {TRUE}를 반환하는 경우 가상 전달로 호출할 수 있으나 그렇지 않은 경우 직접 호출해야 합니다.

__mcall_is_in_vbase(D, f)

f가 D의 가상 기본 클래스에 있는 비정적 구성원 함수이면 {TRUE}를 반환하고, 그렇지 않으면 {FALSE}를 반환합니다. {TRUE}를 반환하는 경우 __mcall_offsetof_vbase(D, f)를 사용하여 this 조정을 수행해야 하고, 그렇지 않으면 __mcall_this_offset(D, f)를 수행해야 합니다.

__mcall_offsetof_vbase(D, f)

여기서 D 클래스 형식 및 f는 D의 가상 기본 클래스에 정의된 비정적 구성원 함수입니다. 즉, __mcall_is_in_vbase(D,f)가 TRUE를 반환합니다.

이것은 기본 오프셋(D 개체의 시작부터 f가 정의된 기본의 시작까지)이 있는 vtable 슬롯의 vtable에서 음의 오프셋이 있는 위치에 반환됩니다.

이것은 D에 대한 포인터를 사용하여 f를 호출할 때 필요한 this 조정입니다.

참고

오프셋은 이후에 vtable 포인터에서 빼야 하는 양수를 반환합니다.

__mcall_this_offset(D, f)

여기서 D 클래스 형식과 f는 D 또는 D의 가상이 아닌 기본 클래스에 정의된 비정적 구성원 함수입니다.

D 개체의 시작부터 f가 정의된 기본의 시작까지 오프셋을 반환합니다. 이것은 D에 대한 포인터를 사용하여 f를 호출할 때 필요한 this 조정입니다. f가 D에 있으면 0이거나 __offsetof_base(D,B)와 같습니다. 여기서 B는 f가 포함된 D의 가상이 아닌 기본 클래스입니다.

7-26 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 191: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

f가 D의 가상 기본 클래스에 있을 때 __mcall_this_offset(D,f)를 사용하면 임의 값을 반환합니다. 이 값을 사용하는 경우에는 어셈블리 오류가 발생하도록 지정되어 있습니다. 따라서 건너뛰어야 할 어셈블리 코드의 섹션에서 __mcall_this_offset을 잘못 사용할 수 있습니다.

__vcall_offsetof_vfunc(D, f)

여기서 D는 클래스이며 f는 D 또는 D의 기본 클래스에 정의된 가상 함수입니다.

이 함수는 기본 오프셋이 있는 vtable 슬롯에서 음의 오프셋을 반환합니다. 기본 오프셋은 D 객체에서 f가 정의된 기본의 시작까지의 거리로 계산됩니다.

f가 가상 구성원 함수가 아닐 때 __vcall_offsetof_vfunc(D, f)를 사용하면 임의 값을 반환합니다. 이 값을 사용하는 경우에는 어셈블리 오류가 발생하도록 지정되어 있습니다.

7.2.9 비정적 구성원 함수 호출

__mcall 및 __vcall로 시작하는 키워드를 사용하여 __asm 함수에서 가상 및 가상이 아닌 함수를 호출할 수 있습니다. 자세한 내용은 7-25페이지의 구성원 함수 클래스에 대한 키워드를 참조하십시오. 정적 구성원 함수에 다른 매개변수가 있어(즉, this가 없음) 호출 사이트가 이미 정적 구성원 함수를 호출하도록 지정되어 있을 수 있으므로 정적 구성원 함수를 검색할 수 있는 __mcall_is_static이 없습니다.

가상이 아닌 구성원 함수 호출

예제 7-6에서는 다음 코드를 사용하여 가상 또는 가상이 아닌 기본에서 가상이 아닌 함수를 호출하는 방법을 보여 줍니다.

예제 7-6 가상이 아닌 함수 호출

// rp contains a D* and we want to do the equivalent of rp->f() where f is a// nonvirtual function// all arguments other than the this pointer are already setup// assumes f does not return a structif __mcall_is_in_vbase(D, f)LDR r12, [rp] // fetch vtable pointerLDR r0, [r12, #-__mcall_offsetof_vbase(D, f)] // fetch the vbase offsetADD r0, r0, rp // do this adjustment

else

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-27ID090708 Non-Confidential, Unrestricted Access

Page 192: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

ADD r0, rp, #__mcall_this_offset(D, f) // set up and adjust this// pointer for D*

endifBL __cpp(&D::f) // call D::f

가상 구성원 함수 호출

예제 7-7에서는 가상 또는 가상이 아닌 기본에서 가상 함수를 호출하는 데 사용할 수 있는 코드를 보여 줍니다.

예제 7-7 가상 함수 호출

// rp contains a D* and we want to do the equivalent of rp->f() where f is a// virtual function// all arguments other than the this pointer are already setup// assumes f does not return a structif __mcall_is_in_vbase(D, f) LDR r12, [rp] // fetch vtable pointer

LDR r0, [r12, #-__mcall_offsetof_vbase(D, f)] // fetch the base offset ADD r0, r0, rp // do this adjustment

LDR r12, [r0] // fetch vbase vtable pointerelse MOV r0, rp // set up this pointer for D* LDR r12, [rp] // fetch vtable pointer ADD r0, r0, #__mcall_this_offset(D, f) // do this adjustmentendif MOV lr, pc // prepare lr LDR pc, [r12, #__vcall_offsetof_vfunc(D, f)] // calls rp->f()

7-28 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 193: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

7.3 sp, lr 또는 pc에 액세스하는 레거시 인라인 어셈블러

ADS(ARM Developer Suite) 버전 1.2 이하의 컴파일러에서는 인라인 어셈블러 코드(7-2페이지의 인라인 어셈블러 참조)에서 sp(r13), lr(r14) 및 pc(r15)에 액세스할 수 있었습니다. 예제 7-8에서는 레거시 인라인 어셈블리 코드에서 lr을 사용할 수 있는 방법을 보여 줍니다.

예제 7-8 lr을 사용하는 레거시 인라인 어셈블리 코드

void func(){ int var; __asm { mov var, lr /* get the return address of func() */ }}

레거시 코드가 인라인 어셈블리에서 lr을 사용하는 경우 lr에 함수의 반환 주소가 반드시 포함되지는 않습니다. 예를 들어 다른 용도로 lr을 사용할 수 있는 특정 빌드 옵션이나 최적화가 있습니다. RVCT 버전 2.0 이상의 컴파일러에서는 lr, sp 또는 pc를 다음과 같이 사용하는 경우 아래와 유사한 오류를 보고합니다.

C 또는 C++ 소스 파일 내에서 이러한 레지스터에 액세스해야 하는 경우 다음을 수행할 수 있습니다.

• 임베디드 어셈블러(7-19페이지의 임베디드 어셈블러 참조)를 사용합니다.

• 인라인 어셈블러에서 다음 내장 함수를 사용합니다.

__current_pc() pc 레지스터에 액세스할 때 사용합니다.

__current_sp() sp 레지스터에 액세스할 때 사용합니다.

__return_address() lr 레지스터에 액세스할 때 사용합니다.

추가 참고:

• 7-30페이지의 레거시 코드에서 sp(r13), lr(r14) 및 pc(r15) 액세스

• 컴파일러 참조 설명서의 4-76페이지의 명령어 내장 함수

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-29ID090708 Non-Confidential, Unrestricted Access

Page 194: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

7.3.1 레거시 코드에서 sp(r13), lr(r14) 및 pc(r15) 액세스

다음 방법을 사용하면 소스 코드에서 sp, lr 및 pc 레지스터에 올바로 액세스할 수 있습니다.

방법 1 인라인 어셈블러에서 다음과 같이 컴파일러 내장 함수를 사용합니다.

void printReg(){ unsigned int spReg, lrReg, pcReg; __asm

{ MOV spReg, __current_sp() MOV pcReg, __current_pc() MOV lrReg, __return_address() } printf("SP = 0x%X\n",spReg); printf("PC = 0x%X\n",pcReg); printf("LR = 0x%X\n",lrReg);}

방법 2 임베디드 어셈블리를 사용하면 C 또는 C++ 소스 파일 내에서 다음과 같이 물리 ARM 레지스터에 액세스할 수 있습니다.

__asm void func(){ MOV r0, lr ... BX lr}

이 방법을 사용하면, 예를 들어 디버깅 목적으로 호출 트리를 표시하기 위해 함수의 반환 주소를 캡처하고 표시할 수 있습니다.

7-19페이지의 임베디드 어셈블러를 참조하십시오.

참고

컴파일러에서 함수를 호출자 함수로 인라인할 수도 있습니다. 함수가 인라인되면 반환 주소는 인라인된 함수를 호출하는 함수의 반환 주소가 됩니다. 또한 함수가 마무리 호출될 수 있습니다.

컴파일러 참조 설명서의 4-97페이지의 __return_address를 참조하십시오.

7-30 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708

Page 195: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

7.4 인라인 어셈블리 코드와 임베디드 어셈블리 코드의 차이점

인라인 어셈블리와 임베디드 어셈블리는 컴파일하는 방식이 서로 다릅니다.

• 인라인 어셈블리 코드는 상위 수준의 프로세서 추상화를 사용하며 코드 생성 중에 C 및 C++ 코드와 통합됩니다. 따라서 컴파일러에서 C 및 C++ 코드와 어셈블러 코드를 함께 최적화합니다.

• 인라인 어셈블리 코드와 달리 임베디드 어셈블리 코드는 C 및 C++ 코드와 따로 어셈블되어 컴파일된 개체를 생성합니다. 이후에 이 개체는 C 또는 C++ 소스의 컴파일을 통해 생성된 개체와 결합합니다.

• 컴파일러로 인라인 어셈블리 코드를 인라인할 수 있지만 임베디드 어셈블리 코드는 암시적으로나 명시적으로나 인라인할 수 없습니다.

표 7-1에서는 인라인 어셈블러와 임베디드 어셈블러의 주요 차이점을 간단히 설명합니다.

표 7-1 인라인 어셈블러와 임베디드 어셈블러의 차이점

기능 임베디드 어셈블러 인라인 어셈블러

명령어 세트 ARM 및 Thumb ARM만

ARM 어셈블러 지시어 모두 지원 지원 안 됨

ARMv6 명령어 모두 지원 SETEND 및 일부 시스템 확장을 제외한 대부분의 명령어를 지원합니다. 전체 ARMv6 SIMD 명령어 세트도 지원됩니다.

ARMv7 명령어 모두 지원 지원되지 않음

C/C++ 식 상수 식만 모든 C/C++ 식

어셈블리 코드의 최적화 최적화 안 함 모두 최적화

인라인 불가능 가능

ARM DUI 0205IK Copyright © 2002-2009 ARM Limited. All rights reserved. 7-31ID090708 Non-Confidential, Unrestricted Access

Page 196: RealView Compilation Tools - ARM architectureinfocenter.arm.com/help/topic/com.arm.doc.dui0205ik/DUI0205IK_rvct... · 2011/7/1  · 이 설명서는 원래 C 언어 디자이너 및

인라인 및 임베디드 어셈블러 사용

7-22페이지의 임베디드 어셈블리 식과 C 또는 C++ 식의 차이점도 참조하십시오.

레지스터 액세스 지정된 물리 레지스터 사용. PC, LR 및 SP도 사용 가능

가상 레지스터 사용(7-9페이지의 가상 레지스터 참조). sp(r13), lr(r14) 및 pc(r15) 사용 시 오류 발생 자세한 내용은 7-29페이지의 sp, lr 또는 pc에 액세스하는 레거시 인라인 어셈블러를 참조하십시오.

명령어 반환 코드에 추가해야 함 자동 생성됨 (BX, BXJ 및 BLX 명령어는 지원되지 않음)

BKPT 명령어 직접 지원됨 지원되지 않음

표 7-1 인라인 어셈블러와 임베디드 어셈블러의 차이점 (계속)

기능 임베디드 어셈블러 인라인 어셈블러

7-32 Copyright © 2002-2009 ARM Limited. All rights reserved. ARM DUI 0205IKNon-Confidential, Unrestricted Access ID090708