forked from OSchip/llvm-project
[mips] Add `short_call` to the set of `long_call/far/near` attributes
MIPS gcc supports `long_call/far/near` attributes only, but other targets have the `short_call` attribut, so let's support it for MIPS for consistency. llvm-svn: 308719
This commit is contained in:
parent
2b13913b12
commit
d5c937b3a3
|
@ -1195,7 +1195,7 @@ def MipsLongCall : InheritableAttr, TargetSpecificAttr<TargetMips> {
|
|||
}
|
||||
|
||||
def MipsShortCall : InheritableAttr, TargetSpecificAttr<TargetMips> {
|
||||
let Spellings = [GCC<"near">];
|
||||
let Spellings = [GCC<"short_call">, GCC<"near">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [MipsShortCallStyleDocs];
|
||||
}
|
||||
|
|
|
@ -1348,13 +1348,14 @@ def MipsShortCallStyleDocs : Documentation {
|
|||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
Clang supports the ``__attribute__((long_call))``, ``__attribute__((far))``,
|
||||
and ``__attribute__((near))`` attributes on MIPS targets. These attributes may
|
||||
only be added to function declarations and change the code generated
|
||||
by the compiler when directly calling the function. The ``near`` attribute
|
||||
allows calls to the function to be made using the ``jal`` instruction, which
|
||||
requires the function to be located in the same naturally aligned 256MB
|
||||
segment as the caller. The ``long_call`` and ``far`` attributes are synonyms
|
||||
and require the use of a different call sequence that works regardless
|
||||
``__attribute__((short__call))``, and ``__attribute__((near))`` attributes
|
||||
on MIPS targets. These attributes may only be added to function declarations
|
||||
and change the code generated by the compiler when directly calling
|
||||
the function. The ``short_call`` and ``near`` attributes are synonyms and
|
||||
allow calls to the function to be made using the ``jal`` instruction, which
|
||||
requires the function to be located in the same naturally aligned 256MB segment
|
||||
as the caller. The ``long_call`` and ``far`` attributes are synonyms and
|
||||
require the use of a different call sequence that works regardless
|
||||
of the distance between the functions.
|
||||
|
||||
These attributes have no effect for position-independent code.
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
// RUN: %clang_cc1 -triple mips-linux-gnu -emit-llvm -o - %s | FileCheck %s
|
||||
|
||||
void __attribute__((long_call)) foo1 (void);
|
||||
void __attribute__((short_call)) foo4 (void);
|
||||
|
||||
void __attribute__((far)) foo2 (void) {}
|
||||
|
||||
// CHECK: define void @foo2() [[FAR:#[0-9]+]]
|
||||
|
||||
void __attribute__((near)) foo3 (void) { foo1(); }
|
||||
void __attribute__((near)) foo3 (void) { foo1(); foo4(); }
|
||||
|
||||
// CHECK: define void @foo3() [[NEAR:#[0-9]+]]
|
||||
|
||||
// CHECK: declare void @foo1() [[LONGDECL:#[0-9]+]]
|
||||
// CHECK: declare void @foo4() [[SHORTDECL:#[0-9]+]]
|
||||
|
||||
// CHECK: attributes [[FAR]] = { {{.*}} "long-call" {{.*}} }
|
||||
// CHECK: attributes [[NEAR]] = { {{.*}} "short-call" {{.*}} }
|
||||
// CHECK: attributes [[LONGDECL]] = { {{.*}} "long-call" {{.*}} }
|
||||
// CHECK: attributes [[SHORTDECL]] = { {{.*}} "short-call" {{.*}} }
|
||||
|
|
|
@ -1,18 +1,25 @@
|
|||
// RUN: %clang_cc1 -triple mips-linux-gnu -fsyntax-only -verify %s
|
||||
|
||||
__attribute__((long_call(0))) void foo1(); // expected-error {{'long_call' attribute takes no arguments}}
|
||||
__attribute__((short_call(0))) void foo9(); // expected-error {{'short_call' attribute takes no arguments}}
|
||||
__attribute__((far(0))) void foo2(); // expected-error {{'far' attribute takes no arguments}}
|
||||
__attribute__((near(0))) void foo3(); // expected-error {{'near' attribute takes no arguments}}
|
||||
|
||||
__attribute((long_call)) int a; // expected-warning {{attribute only applies to functions}}
|
||||
__attribute((short_call)) int d; // expected-warning {{attribute only applies to functions}}
|
||||
__attribute((far)) int a; // expected-warning {{attribute only applies to functions}}
|
||||
__attribute((near)) int a; // expected-warning {{attribute only applies to functions}}
|
||||
|
||||
__attribute((long_call)) void foo4();
|
||||
__attribute((short_call)) void foo10();
|
||||
__attribute((far)) void foo5();
|
||||
__attribute((near)) void foo6();
|
||||
|
||||
__attribute((long_call, far)) void foo7();
|
||||
__attribute((short_call, near)) void foo11();
|
||||
|
||||
__attribute((far, near)) void foo8(); // expected-error {{'far' and 'near' attributes are not compatible}} \
|
||||
// expected-note {{conflicting attribute is here}}
|
||||
|
||||
__attribute((short_call, long_call)) void foo12(); // expected-error {{'short_call' and 'long_call' attributes are not compatible}} \
|
||||
// expected-note {{conflicting attribute is here}}
|
||||
|
|
Loading…
Reference in New Issue