Skip to content

Commit a59bffb

Browse files
committedSep 5, 2019
[ARM] Add support for the s,j,x,N,O inline asm constraints
A number of inline assembly constraints are currently supported by LLVM, but rejected as invalid by Clang: Target independent constraints: s: An integer constant, but allowing only relocatable values ARM specific constraints: j: An immediate integer between 0 and 65535 (valid for MOVW) x: A 32, 64, or 128-bit floating-point/SIMD register: s0-s15, d0-d7, or q0-q3 N: An immediate integer between 0 and 31 (Thumb1 only) O: An immediate integer which is a multiple of 4 between -508 and 508. (Thumb1 only) This patch adds support to Clang for the missing constraints along with some checks to ensure that the constraints are used with the correct target and Thumb mode, and that immediates are within valid ranges (at least where possible). The constraints are already implemented in LLVM, but just a couple of minor corrections to checks (V8M Baseline includes MOVW so should work with 'j', 'N' and 'O' shouldn't be valid in Thumb2) so that Clang and LLVM are in line with each other and the documentation. Differential Revision: https://reviews.llvm.org/D65863 Change-Id: I18076619e319bac35fbb60f590c069145c9d9a0a llvm-svn: 371079
1 parent 29361c7 commit a59bffb

File tree

3 files changed

+396
-8
lines changed

3 files changed

+396
-8
lines changed
 

‎clang/lib/Basic/Targets/ARM.cpp

+88-5
Original file line numberDiff line numberDiff line change
@@ -885,19 +885,102 @@ bool ARMTargetInfo::validateAsmConstraint(
885885
switch (*Name) {
886886
default:
887887
break;
888-
case 'l': // r0-r7
889-
case 'h': // r8-r15
890-
case 't': // VFP Floating point register single precision
891-
case 'w': // VFP Floating point register double precision
888+
case 'l': // r0-r7 if thumb, r0-r15 if ARM
892889
Info.setAllowsRegister();
893890
return true;
891+
case 'h': // r8-r15, thumb only
892+
if (isThumb()) {
893+
Info.setAllowsRegister();
894+
return true;
895+
}
896+
break;
897+
case 's': // An integer constant, but allowing only relocatable values.
898+
return true;
899+
case 't': // s0-s31, d0-d31, or q0-q15
900+
case 'w': // s0-s15, d0-d7, or q0-q3
901+
case 'x': // s0-s31, d0-d15, or q0-q7
902+
Info.setAllowsRegister();
903+
return true;
904+
case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
905+
// only available in ARMv6T2 and above
906+
if (CPUAttr.equals("6T2") || ArchVersion >= 7) {
907+
Info.setRequiresImmediate(0, 65535);
908+
return true;
909+
}
910+
break;
894911
case 'I':
912+
if (isThumb()) {
913+
if (!supportsThumb2())
914+
Info.setRequiresImmediate(0, 255);
915+
else
916+
// FIXME: should check if immediate value would be valid for a Thumb2
917+
// data-processing instruction
918+
Info.setRequiresImmediate();
919+
} else
920+
// FIXME: should check if immediate value would be valid for an ARM
921+
// data-processing instruction
922+
Info.setRequiresImmediate();
923+
return true;
895924
case 'J':
925+
if (isThumb() && !supportsThumb2())
926+
Info.setRequiresImmediate(-255, -1);
927+
else
928+
Info.setRequiresImmediate(-4095, 4095);
929+
return true;
896930
case 'K':
931+
if (isThumb()) {
932+
if (!supportsThumb2())
933+
// FIXME: should check if immediate value can be obtained from shifting
934+
// a value between 0 and 255 left by any amount
935+
Info.setRequiresImmediate();
936+
else
937+
// FIXME: should check if immediate value would be valid for a Thumb2
938+
// data-processing instruction when inverted
939+
Info.setRequiresImmediate();
940+
} else
941+
// FIXME: should check if immediate value would be valid for an ARM
942+
// data-processing instruction when inverted
943+
Info.setRequiresImmediate();
944+
return true;
897945
case 'L':
946+
if (isThumb()) {
947+
if (!supportsThumb2())
948+
Info.setRequiresImmediate(-7, 7);
949+
else
950+
// FIXME: should check if immediate value would be valid for a Thumb2
951+
// data-processing instruction when negated
952+
Info.setRequiresImmediate();
953+
} else
954+
// FIXME: should check if immediate value would be valid for an ARM
955+
// data-processing instruction when negated
956+
Info.setRequiresImmediate();
957+
return true;
898958
case 'M':
899-
// FIXME
959+
if (isThumb() && !supportsThumb2())
960+
// FIXME: should check if immediate value is a multiple of 4 between 0 and
961+
// 1020
962+
Info.setRequiresImmediate();
963+
else
964+
// FIXME: should check if immediate value is a power of two or a integer
965+
// between 0 and 32
966+
Info.setRequiresImmediate();
900967
return true;
968+
case 'N':
969+
// Thumb1 only
970+
if (isThumb() && !supportsThumb2()) {
971+
Info.setRequiresImmediate(0, 31);
972+
return true;
973+
}
974+
break;
975+
case 'O':
976+
// Thumb1 only
977+
if (isThumb() && !supportsThumb2()) {
978+
// FIXME: should check if immediate value is a multiple of 4 between -508
979+
// and 508
980+
Info.setRequiresImmediate();
981+
return true;
982+
}
983+
break;
901984
case 'Q': // A memory address that is a single base register.
902985
Info.setAllowsMemory();
903986
return true;

0 commit comments

Comments
 (0)
Please sign in to comment.