中文
注册
我要评分
文档获取效率
文档正确性
内容完整性
文档易理解
在线提单
论坛求助

选项 -mcmodel=medium,-mlarge-data-threshold=n

说明

此选项使能了32bit之外的动态取址操作。在使用-mcmodel=medium时,对于符号size大于aarch64_data_threshold的符号使用通过mov序列来获取PC值的offset,再与PC值相加的方式实现64bit的相对PC寻址,在地址无关选项打开时,可以实现64bit相对PC寻址,获取GOT表入口,并且通过mov序列+LDR方式获取符号。

注:aarch64_data_threshold默认值为2^16 = 65536,用户可以使用-mlarge-data-threshold=n选项指定大符号的阈值为n。

举例

如下图1,假设foovar的符号距离寻址指令的距离大于4GB,-mcmodel=small使用ADRP+ADD指令进行符号拿取,而foovar在链接时计算距离的方式是.bss+size方式,在链接时会报relocation truncated to fit错误。在此使用图2中的mov序列+PC寻址方式可将寻址范围扩大至64位,解决由于地址溢出导致的报错。

图1 smallcode model寻址方式
图2 mov序列+PC寻址方式

使用方法

用例:hello.f90

编译命令:

1
gfortran -mcmodel=medium hello.f90 -o hello.out -mlarge-data-threshold=1

hello.f90用例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
program main
common/baz/a,b,c
real a,b,c
b = 0.0
call foo()
print*, b
end

subroutine foo()
common/baz/a,b,c
real a,b,c

integer, parameter :: nx = 1024
integer, parameter :: ny = 1024
integer, parameter :: nz = 1024
integer, parameter :: nf = 1
real :: bar(nf,nx*ny*nz)
real :: bar1(nf,nx*ny*nz)
!real, allocatable,dimension(:,:) :: bar
!allocate(bar(nf,nx*ny*nz))

bar = 1.0
b = bar(1,320*138*420)
b = bar1(1,321*138*420)

return
end

结果

此例中有size=1024*1024*1024的大符号bar1,其阈值大于-mlarge-data-threshold=1选项指定的阈值,因此实现了64bit的相对PC寻址。

如下图所示,如果不加-mcmodel=medium,bar1符号就无法寻址,会报错。

提示

在GCC for openEuler使用过程中,若出现以下错误,可以尝试添加编译选项-mcmodel=medium -mlarge-data-threshold=1解决。