base.isa revision 2482
1////////////////////////////////////////////////////////////////////
2//
3// Base class for sparc instructions, and some support functions
4//
5
6output header {{
7
8        union CondCodes
9        {
10            struct
11            {
12                uint8_t c:1;
13                uint8_t v:1;
14                uint8_t z:1;
15                uint8_t n:1;
16            };
17            uint32_t bits;
18        };
19
20        enum CondTest
21        {
22            Always=0x8,
23            Never=0x0,
24            NotEqual=0x9,
25            Equal=0x1,
26            Greater=0xA,
27            LessOrEqual=0x2,
28            GreaterOrEqual=0xB,
29            Less=0x3,
30            GreaterUnsigned=0xC,
31            LessOrEqualUnsigned=0x4,
32            CarryClear=0xD,
33            CarrySet=0x5,
34            Positive=0xE,
35            Negative=0x6,
36            OverflowClear=0xF,
37            OverflowSet=0x7
38        };
39
40        /**
41         * Base class for all SPARC static instructions.
42         */
43        class SparcStaticInst : public StaticInst
44        {
45          protected:
46            // Constructor.
47            SparcStaticInst(const char *mnem,
48                 MachInst _machInst, OpClass __opClass)
49                    : StaticInst(mnem, _machInst, __opClass)
50                {
51                }
52
53            std::string generateDisassembly(Addr pc,
54                const SymbolTable *symtab) const;
55
56            void printReg(std::ostream &os, int reg) const;
57        };
58
59        bool passesCondition(uint32_t codes, uint32_t condition);
60}};
61
62def template ROrImmDecode {{
63    {
64        return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
65                  : (SparcStaticInst *)(new %(class_name)s(machInst)));
66    }
67}};
68
69let {{
70    def splitOutImm(code):
71        matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>d{0,2})')
72        rOrImmMatch = matcher.search(code)
73        if (rOrImmMatch == None):
74            return (False, CodeBlock(code), None, '', '')
75        rString = matcher.sub(r'(?P=rNum)', rOrImmMatch.string)
76        iString = matcher.sub(r'(?P=iNum)', rOrImmMatch.string)
77        orig_code = code
78        code = matcher.sub(r'Rs(?P<rNum>)', orig_code)
79        imm_code = matcher.sub('imm', orig_code)
80        return (True, CodeBlock(code), CodeBlock(imm_code), rString, iString)
81}};
82
83output decoder {{
84
85        void
86        SparcStaticInst::printReg(std::ostream &os, int reg) const
87        {
88            if (reg < FP_Base_DepTag) {
89                ccprintf(os, "r%d", reg);
90            }
91            else {
92                ccprintf(os, "f%d", reg - FP_Base_DepTag);
93            }
94        }
95
96        std::string SparcStaticInst::generateDisassembly(Addr pc,
97            const SymbolTable *symtab) const
98        {
99            std::stringstream ss;
100
101            ccprintf(ss, "%-10s ", mnemonic);
102
103            // just print the first two source regs... if there's
104            // a third one, it's a read-modify-write dest (Rc),
105            // e.g. for CMOVxx
106            if(_numSrcRegs > 0)
107            {
108                printReg(ss, _srcRegIdx[0]);
109            }
110            if(_numSrcRegs > 1)
111            {
112                ss << ",";
113                printReg(ss, _srcRegIdx[1]);
114            }
115
116            // just print the first dest... if there's a second one,
117            // it's generally implicit
118            if(_numDestRegs > 0)
119            {
120                if(_numSrcRegs > 0)
121                    ss << ",";
122                    printReg(ss, _destRegIdx[0]);
123            }
124
125            return ss.str();
126        }
127
128        bool passesCondition(uint32_t codes, uint32_t condition)
129        {
130            CondCodes condCodes;
131            condCodes.bits = codes;
132            switch(condition)
133            {
134              case Always:
135                return true;
136              case Never:
137                return false;
138              case NotEqual:
139                return !condCodes.z;
140              case Equal:
141                return condCodes.z;
142              case Greater:
143                return !(condCodes.z | (condCodes.n ^ condCodes.v));
144              case LessOrEqual:
145                return condCodes.z | (condCodes.n ^ condCodes.v);
146              case GreaterOrEqual:
147                return !(condCodes.n ^ condCodes.v);
148              case Less:
149                return (condCodes.n ^ condCodes.v);
150              case GreaterUnsigned:
151                return !(condCodes.c | condCodes.z);
152              case LessOrEqualUnsigned:
153                return (condCodes.c | condCodes.z);
154              case CarryClear:
155                return !condCodes.c;
156              case CarrySet:
157                return condCodes.c;
158              case Positive:
159                return !condCodes.n;
160              case Negative:
161                return condCodes.n;
162              case OverflowClear:
163                return !condCodes.v;
164              case OverflowSet:
165                return condCodes.v;
166            }
167            panic("Tried testing condition nonexistant "
168                    "condition code %d", condition);
169        }
170}};
171
172