xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Xtensa/XtensaUtils.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*0fca6ea1SDimitry Andric //===--- XtensaUtils.cpp ---- Xtensa Utility Functions ----------*- C++ -*-===//
2*0fca6ea1SDimitry Andric //
3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0fca6ea1SDimitry Andric //
7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
8*0fca6ea1SDimitry Andric //
9*0fca6ea1SDimitry Andric // This file contains miscellaneous utility functions.
10*0fca6ea1SDimitry Andric //
11*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
12*0fca6ea1SDimitry Andric 
13*0fca6ea1SDimitry Andric #include "XtensaUtils.h"
14*0fca6ea1SDimitry Andric 
15*0fca6ea1SDimitry Andric namespace llvm {
16*0fca6ea1SDimitry Andric 
17*0fca6ea1SDimitry Andric bool isValidAddrOffset(int Scale, int64_t OffsetVal) {
18*0fca6ea1SDimitry Andric   bool Valid = false;
19*0fca6ea1SDimitry Andric 
20*0fca6ea1SDimitry Andric   switch (Scale) {
21*0fca6ea1SDimitry Andric   case 1:
22*0fca6ea1SDimitry Andric     Valid = (OffsetVal >= 0 && OffsetVal <= 255);
23*0fca6ea1SDimitry Andric     break;
24*0fca6ea1SDimitry Andric   case 2:
25*0fca6ea1SDimitry Andric     Valid = (OffsetVal >= 0 && OffsetVal <= 510) && ((OffsetVal & 0x1) == 0);
26*0fca6ea1SDimitry Andric     break;
27*0fca6ea1SDimitry Andric   case 4:
28*0fca6ea1SDimitry Andric     Valid = (OffsetVal >= 0 && OffsetVal <= 1020) && ((OffsetVal & 0x3) == 0);
29*0fca6ea1SDimitry Andric     break;
30*0fca6ea1SDimitry Andric   default:
31*0fca6ea1SDimitry Andric     break;
32*0fca6ea1SDimitry Andric   }
33*0fca6ea1SDimitry Andric   return Valid;
34*0fca6ea1SDimitry Andric }
35*0fca6ea1SDimitry Andric 
36*0fca6ea1SDimitry Andric bool isValidAddrOffset(MachineInstr &MI, int64_t Offset) {
37*0fca6ea1SDimitry Andric   int Scale = 0;
38*0fca6ea1SDimitry Andric 
39*0fca6ea1SDimitry Andric   switch (MI.getOpcode()) {
40*0fca6ea1SDimitry Andric   case Xtensa::L8UI:
41*0fca6ea1SDimitry Andric   case Xtensa::S8I:
42*0fca6ea1SDimitry Andric     Scale = 1;
43*0fca6ea1SDimitry Andric     break;
44*0fca6ea1SDimitry Andric   case Xtensa::L16SI:
45*0fca6ea1SDimitry Andric   case Xtensa::L16UI:
46*0fca6ea1SDimitry Andric   case Xtensa::S16I:
47*0fca6ea1SDimitry Andric     Scale = 2;
48*0fca6ea1SDimitry Andric     break;
49*0fca6ea1SDimitry Andric   case Xtensa::LEA_ADD:
50*0fca6ea1SDimitry Andric     return (Offset >= -128 && Offset <= 127);
51*0fca6ea1SDimitry Andric   default:
52*0fca6ea1SDimitry Andric     // assume that MI is 32-bit load/store operation
53*0fca6ea1SDimitry Andric     Scale = 4;
54*0fca6ea1SDimitry Andric     break;
55*0fca6ea1SDimitry Andric   }
56*0fca6ea1SDimitry Andric   return isValidAddrOffset(Scale, Offset);
57*0fca6ea1SDimitry Andric }
58*0fca6ea1SDimitry Andric 
59*0fca6ea1SDimitry Andric } // namespace llvm
60