124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- DNBArchImpl.h -------------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  Created by Greg Clayton on 6/25/07.
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifndef __DebugNubArchMachPPC_h__
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#define __DebugNubArchMachPPC_h__
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__)
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DNBArch.h"
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass MachThread;
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass DNBArchMachPPC : public DNBArchProtocol
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic:
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DNBArchMachPPC(MachThread *thread) :
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_thread(thread),
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_state()
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual ~DNBArchMachPPC()
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual const DNBRegisterSetInfo *
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            GetRegisterSetInfo(nub_size_t *num_reg_sets) const;
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual bool            GetRegisterValue(int set, int reg, DNBRegisterValue *value) const;
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual kern_return_t   GetRegisterState  (int set, bool force);
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual kern_return_t   SetRegisterState  (int set);
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual bool            RegisterSetStateIsValid (int set) const;
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual uint64_t        GetPC(uint64_t failValue);    // Get program counter
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual kern_return_t   SetPC(uint64_t value);
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual uint64_t        GetSP(uint64_t failValue);    // Get stack pointer
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual bool            ThreadWillResume();
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    virtual bool            ThreadDidStop();
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    static const uint8_t * const SoftwareBreakpointOpcode (nub_size_t byte_size);
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    static uint32_t         GetCPUType();
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprotected:
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    kern_return_t    EnableHardwareSingleStep (bool enable);
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    typedef enum RegisterSetTag
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        e_regSetALL = REGISTER_SET_ALL,
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        e_regSetGPR,
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        e_regSetFPR,
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        e_regSetEXC,
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        e_regSetVEC,
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        kNumRegisterSets
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    } RegisterSet;
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    typedef enum RegisterSetWordSizeTag
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        e_regSetWordSizeGPR = PPC_THREAD_STATE_COUNT,
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        e_regSetWordSizeFPR = PPC_FLOAT_STATE_COUNT,
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        e_regSetWordSizeEXC = PPC_EXCEPTION_STATE_COUNT,
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        e_regSetWordSizeVEC = PPC_VECTOR_STATE_COUNT
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    } RegisterSetWordSize;
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    enum
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Read = 0,
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Write = 1,
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        kNumErrors = 2
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    };
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    struct State
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ppc_thread_state_t        gpr;
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ppc_float_state_t        fpr;
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ppc_exception_state_t    exc;
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ppc_vector_state_t        vec;
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        kern_return_t            gpr_errs[2];    // Read/Write errors
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        kern_return_t            fpr_errs[2];    // Read/Write errors
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        kern_return_t            exc_errs[2];    // Read/Write errors
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        kern_return_t            vec_errs[2];    // Read/Write errors
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        State()
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            uint32_t i;
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            for (i=0; i<kNumErrors; i++)
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                gpr_errs[i] = -1;
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                fpr_errs[i] = -1;
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                exc_errs[i] = -1;
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                vec_errs[i] = -1;
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        void InvalidateAllRegisterStates()
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            SetError (e_regSetALL, Read, -1);
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        kern_return_t GetError (int set, uint32_t err_idx) const
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (err_idx < kNumErrors)
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                switch (set)
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // When getting all errors, just OR all values together to see if
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // we got any kind of error.
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case e_regSetALL:    return gpr_errs[err_idx] | fpr_errs[err_idx] | exc_errs[err_idx] | vec_errs[err_idx];
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case e_regSetGPR:    return gpr_errs[err_idx];
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case e_regSetFPR:    return fpr_errs[err_idx];
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case e_regSetEXC:    return exc_errs[err_idx];
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case e_regSetVEC:    return vec_errs[err_idx];
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                default: break;
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return -1;
12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        bool SetError (int set, uint32_t err_idx, kern_return_t err)
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (err_idx < kNumErrors)
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                switch (set)
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case e_regSetALL:
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    gpr_errs[err_idx] = fpr_errs[err_idx] = exc_errs[err_idx] = vec_errs[err_idx] = err;
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    return true;
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case e_regSetGPR:
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    gpr_errs[err_idx] = err;
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    return true;
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case e_regSetFPR:
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    fpr_errs[err_idx] = err;
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    return true;
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case e_regSetEXC:
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    exc_errs[err_idx] = err;
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    return true;
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case e_regSetVEC:
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    vec_errs[err_idx] = err;
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    return true;
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                default: break;
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        bool RegsAreValid (int set) const
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return GetError(set, Read) == KERN_SUCCESS;
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    };
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    kern_return_t GetGPRState (bool force);
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    kern_return_t GetFPRState (bool force);
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    kern_return_t GetEXCState (bool force);
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    kern_return_t GetVECState (bool force);
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    kern_return_t SetGPRState ();
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    kern_return_t SetFPRState ();
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    kern_return_t SetEXCState ();
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    kern_return_t SetVECState ();
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprotected:
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    MachThread *    m_thread;
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    State            m_state;
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif    // #if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__)
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif    // #ifndef __DebugNubArchMachPPC_h__
180