summaryrefslogtreecommitdiff
path: root/arch/sparc/isa/base.isa
blob: 916a9c5a53276d5e4212b91f3c458bfb0b400f08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
////////////////////////////////////////////////////////////////////
//
// Base class for sparc instructions, and some support functions
//

output header {{

        struct condCodes
        {
            uint8_t c:1;
            uint8_t v:1;
            uint8_t z:1;
            uint8_t n:1;
        };

        enum condTest
        {
            Always=0x8,
            Never=0x0,
            NotEqual=0x9,
            Equal=0x1,
            Greater=0xA,
            LessOrEqual=0x2,
            GreaterOrEqual=0xB,
            Less=0x3,
            GreaterUnsigned=0xC,
            LessOrEqualUnsigned=0x4,
            CarryClear=0xD,
            CarrySet=0x5,
            Positive=0xE,
            Negative=0x6,
            OverflowClear=0xF,
            OverflowSet=0x7
        };

        /**
         * Base class for all SPARC static instructions.
         */
        class SparcStaticInst : public StaticInst
        {
          protected:
            // Constructor.
            SparcStaticInst(const char *mnem,
                 MachInst _machInst, OpClass __opClass)
                    : StaticInst(mnem, _machInst, __opClass)
                {
                }

            std::string generateDisassembly(Addr pc,
                const SymbolTable *symtab) const;
        };

        bool passesCondition(condCodes codes, condTest condition);
}};

output decoder {{

        std::string SparcStaticInst::generateDisassembly(Addr pc,
            const SymbolTable *symtab) const
        {
            std::stringstream ss;

            ccprintf(ss, "%-10s ", mnemonic);

            // just print the first two source regs... if there's
            // a third one, it's a read-modify-write dest (Rc),
            // e.g. for CMOVxx
            if(_numSrcRegs > 0)
            {
                printReg(ss, _srcRegIdx[0]);
            }
            if(_numSrcRegs > 1)
            {
                ss << ",";
                printReg(ss, _srcRegIdx[1]);
            }

            // just print the first dest... if there's a second one,
            // it's generally implicit
            if(_numDestRegs > 0)
            {
                if(_numSrcRegs > 0)
                    ss << ",";
                    printReg(ss, _destRegIdx[0]);
            }

            return ss.str();
        }

        bool passesCondition(condCodes codes, condTest condition)
        {
            switch(condition)
            {
              case Always:
                return true;
              case Never:
                return false;
              case NotEqual:
                return !codes.z;
              case Equal:
                return codes.z;
              case Greater:
                return !(codes.z | (codes.n ^ codes.v));
              case LessOrEqual:
                return codes.z | (codes.n ^ codes.v);
              case GreaterOrEqual:
                return !(codes.n ^ codes.v);
              case Less:
                return (codes.n ^ codes.v);
              case GreaterUnsigned:
                return !(codes.c | codes.z);
              case LessOrEqualUnsigned:
                return (codes.c | codes.z);
              case CarryClear:
                return !codes.c;
              case CarrySet:
                return codes.c;
              case Positive:
                return !codes.n;
              case Negative:
                return codes.n;
              case OverflowClear:
                return !codes.v;
              case OverflowSet:
                return codes.v;
            }
        }
}};