diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 684058b1da7200de00ecd9ea73653ba59422633d..77caba2f13996e541b1e5c216a980aa1b91e038e 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -2176,6 +2176,37 @@ s_aarch64_capinit (int ignored ATTRIBUTE_UNUSED) demand_empty_rest_of_line (); } + +static void +s_aarch64_chericap (int ignored ATTRIBUTE_UNUSED) +{ + expressionS exp; + + expression (&exp); + if (exp.X_op != O_symbol) + { + as_bad (_(".chericap expects a target symbol as an argument")); + return; + } + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + + frag_grow (16); + fix_new_aarch64 (frag_now, frag_more (0) - frag_now->fr_literal, 16, &exp, 0, + BFD_RELOC_MORELLO_CAPINIT); + + mapping_state (MAP_DATA); + for (int i = 0; i < 4; i++) + { + /* The documentation of our md_number_to_chars says the greatest value + size it can handle is 4 bytes. */ + char *p = frag_more (4); + md_number_to_chars (p, 0, 4); + } + demand_empty_rest_of_line (); +} #endif /* OBJ_ELF */ static void s_aarch64_arch (int); @@ -2211,6 +2242,7 @@ const pseudo_typeS md_pseudo_table[] = { {"dword", s_aarch64_elf_cons, 8}, {"variant_pcs", s_variant_pcs, 0}, {"capinit", s_aarch64_capinit, 0}, + {"chericap", s_aarch64_chericap, 0}, #endif {"float16", float_cons, 'h'}, {"bfloat16", float_cons, 'b'}, diff --git a/gas/testsuite/gas/aarch64/morello-chericap.d b/gas/testsuite/gas/aarch64/morello-chericap.d new file mode 100644 index 0000000000000000000000000000000000000000..2d855f283a37cd507954da6fdb2b6b7b74294a25 --- /dev/null +++ b/gas/testsuite/gas/aarch64/morello-chericap.d @@ -0,0 +1,61 @@ +#as: -march=armv8-a+c64 +#objdump: -srt + +.*: file format .* + +SYMBOL TABLE: +0000000000000000 l d \.text 0000000000000000 \.text +0000000000000000 l d \.data 0000000000000000 \.data +0000000000000000 l d \.bss 0000000000000000 \.bss +0000000000000000 l O \.data 0000000000000010 bar +0000000000000010 l O \.data 0000000000000010 f\.p +0000000000000000 l d \.rodata 0000000000000000 \.rodata +0000000000000000 l \.rodata 000000000000000c str2 +0000000000000030 l \.data 0000000000000010 a +0000000000000040 l \.data 0000000000000010 b +0000000000000050 l \.data 0000000000000010 c +0000000000000060 l \.data 0000000000000010 d +0000000000000000 l d \.data\.rel\.ro 0000000000000000 \.data\.rel\.ro +0000000000000000 l \.data\.rel\.ro 0000000000000010 e +0000000000000000 g F \.text 0000000000000013 f +0000000000000020 g \.data 000000000000000c str +0000000000000000 \*UND\* 0000000000000000 foo +0000000000000014 g F \.text 0000000000000000 _start + + +RELOCATION RECORDS FOR \[\.text\]: +OFFSET TYPE VALUE +0000000000000014 R_AARCH64_LDST128_ABS_LO12_NC \.data\+0x0000000000000030 + + +RELOCATION RECORDS FOR \[\.data\]: +OFFSET TYPE VALUE +0000000000000000 R_MORELLO_CAPINIT f\+0x000000000000000c +0000000000000010 R_MORELLO_CAPINIT f\+0x000000000000000c +0000000000000030 R_MORELLO_CAPINIT str +0000000000000040 R_MORELLO_CAPINIT str\+0x0000000000000008 +0000000000000050 R_MORELLO_CAPINIT foo\+0x0000000000000010 +0000000000000060 R_MORELLO_CAPINIT a + + +RELOCATION RECORDS FOR \[\.data\.rel\.ro\]: +OFFSET TYPE VALUE +0000000000000000 R_MORELLO_CAPINIT str2 + + +Contents of section \.text: + 0000 fd7bbf62 fdd3c1c2 01000014 fd7bc122 .* + 0010 c053c2c2 420040c2 c053c2c2 .* +Contents of section \.data: + 0000 00000000 00000000 00000000 00000000 .* + 0010 00000000 00000000 00000000 00000000 .* + 0020 48656c6c 6f20576f 726c6400 00000000 .* + 0030 00000000 00000000 00000000 00000000 .* + 0040 00000000 00000000 00000000 00000000 .* + 0050 00000000 00000000 00000000 00000000 .* + 0060 00000000 00000000 00000000 00000000 .* +Contents of section \.rodata: + 0000 48656c6c 6f20576f 726c6400 .* +Contents of section \.data\.rel\.ro: + 0000 00000000 00000000 00000000 00000000 .* + diff --git a/gas/testsuite/gas/aarch64/morello-chericap.s b/gas/testsuite/gas/aarch64/morello-chericap.s new file mode 100644 index 0000000000000000000000000000000000000000..1d44a4ffbb952f13d9abaf4288278d3d06786083 --- /dev/null +++ b/gas/testsuite/gas/aarch64/morello-chericap.s @@ -0,0 +1,79 @@ +// Just using the same testcase as the capinit one, but with capinit switched +// to chericap. chericap does not allocate space so we remove the data +// directives. +// +// On top of that we add a testcase using a more complicated form that these +// directives see in the real world. Just to ensure that works too. + .text + .globl f + .p2align 2 + .type f,@function +f: + stp c29, c30, [csp, #-32]! + mov c29, csp + b .LBB0_1 +.Ltmp0: +.LBB0_1: + ldp c29, c30, [csp], #32 + ret c30 +.Lfunc_end0: + .size f, .Lfunc_end0-f + + .type bar,@object + .data + .p2align 4 +bar: + .chericap f+((.Ltmp0+1)-f) + .size bar, 16 + + .type f.p,@object + .data + .p2align 4 +f.p: + .capinit f+((.Ltmp0+1)-f) + .xword 0 + .xword 0 + .size f.p, 16 + + +.section .rodata +str2: + .string "Hello World" + .size str2, .-str2 + +.data +.globl str +str: + .string "Hello World" + .size str, .-str + +.align 4 +a: + .chericap str + .size a, .-a + +b: + .chericap str+8 + .size b, .-b + +c: + .chericap foo+16 + .size c, .-c + +d: + .chericap a + .size d, .-d + +.section .data.rel.ro +.align 4 +e: + .chericap str2 + .size e, .-e + +.align 4 +.text +.globl _start +.type _start STT_FUNC +_start: + ldr c2, [c2, :lo12:a] + ret