<commit_before>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#ident "Copyright (c) 2007-2012 Tokutek Inc.  All rights reserved."
#ident "$Id$"

#include <config.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <toku_assert.h>
#if defined(HAVE_MALLOC_H)
# include <malloc.h>
#elif defined(HAVE_SYS_MALLOC_H)
# include <sys/malloc.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#if defined(HAVE_SYSCALL_H)
# include <syscall.h>
#elif defined(HAVE_SYS_SYSCALL_H)
# include <sys/syscall.h>
# if !defined(__NR_gettid) && defined(SYS_gettid)
#  define __NR_gettid SYS_gettid
# endif
#endif
#if defined(HAVE_SYS_SYSCTL_H)
# include <sys/sysctl.h>
#endif
#include <inttypes.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/statvfs.h>
#include "toku_portability.h"
#include "toku_os.h"
#include "toku_time.h"
#include "memory.h"

int
toku_portability_init(void) {
    int r = toku_memory_startup();
    return r;
}

void
toku_portability_destroy(void) {
    toku_memory_shutdown();
}

int
toku_os_getpid(void) {
    return getpid();
}

int
toku_os_gettid(void) {
    return syscall(__NR_gettid);
}

int
toku_os_get_number_processors(void) {
    return sysconf(_SC_NPROCESSORS_CONF);
}

#if defined(HAVE_SCHED_GETAFFINITY)
#include <sched.h>
#endif

int
toku_os_get_number_active_processors(void) {
    int n = sysconf(_SC_NPROCESSORS_ONLN);
#if defined(HAVE_SCHED_GETAFFINITY)
    {
        cpu_set_t cpuset;
        int r = sched_getaffinity(getpid(), sizeof cpuset, &cpuset);
        assert(r == 0);
        int ncpus = 0;
        for (unsigned i = 0; i < 8 * sizeof cpuset; i++)
            if (CPU_ISSET(i, &cpuset))
                ncpus++;
        assert(ncpus <= n);
        n = ncpus;
    }
#endif
#define DO_TOKU_NCPUS 1
#if DO_TOKU_NCPUS
    {
        char *toku_ncpus = getenv("TOKU_NCPUS");
        if (toku_ncpus) {
            int ncpus = atoi(toku_ncpus);
            if (ncpus < n)
                n = ncpus;
        }
    }
#endif
    return n;
}

int
toku_os_get_pagesize(void) {
    return sysconf(_SC_PAGESIZE);
}

uint64_t
toku_os_get_phys_memory_size(void) {
#if defined(_SC_PHYS_PAGES)
    uint64_t npages = sysconf(_SC_PHYS_PAGES);
    uint64_t pagesize = sysconf(_SC_PAGESIZE);
    return npages*pagesize;
#elif defined(HAVE_SYS_SYSCTL_H)
    uint64_t memsize;
    size_t len = sizeof memsize;
    sysctlbyname("hw.memsize", &memsize, &len, NULL, 0);
    return memsize;
#else
# error "cannot find _SC_PHYS_PAGES or sysctlbyname()"
#endif
}

int
toku_os_get_file_size(int fildes, int64_t *fsize) {
    toku_struct_stat sbuf;
    int r = fstat(fildes, &sbuf);
    if (r==0) {
        *fsize = sbuf.st_size;
    }
    return r;
}

int
toku_os_get_unique_file_id(int fildes, struct fileid *id) {
    toku_struct_stat statbuf;
    memset(id, 0, sizeof(*id));
    int r=fstat(fildes, &statbuf);
    if (r==0) {
        id->st_dev = statbuf.st_dev;
        id->st_ino = statbuf.st_ino;
    }
    return r;
}

int
toku_os_lock_file(const char *name) {
    int r;
    int fd = open(name, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR);
    if (fd>=0) {
        r = flock(fd, LOCK_EX | LOCK_NB);
        if (r!=0) {
            r = errno; //Save errno from flock.
            close(fd);
            fd = -1; //Disable fd.
            errno = r;
        }
    }
    return fd;
}

int
toku_os_unlock_file(int fildes) {
    int r = flock(fildes, LOCK_UN);
    if (r==0) r = close(fildes);
    return r;
}

int
toku_os_mkdir(const char *pathname, mode_t mode) {
    int r = mkdir(pathname, mode);
    return r;
}

int
toku_os_get_process_times(struct timeval *usertime, struct timeval *kerneltime) {
    int r;
    struct rusage rusage;
    r = getrusage(RUSAGE_SELF, &rusage);
    if (r == -1)
        return get_error_errno();
    if (usertime)
        *usertime = rusage.ru_utime;
    if (kerneltime)
        *kerneltime = rusage.ru_stime;
    return 0;
}

int
toku_os_initialize_settings(int UU(verbosity)) {
    int r = 0;
    static int initialized = 0;
    assert(initialized==0);
    initialized=1;
    return r;
}

int
toku_os_get_max_rss(int64_t *maxrss) {
    char statusname[100];
    sprintf(statusname, "/proc/%d/status", getpid());
    FILE *f = fopen(statusname, "r");
    if (f == NULL) {
#if defined(HAVE_SYS_RESOURCE_H)
        // try getrusage instead
        struct rusage rusage;
        getrusage(RUSAGE_SELF, &rusage);
        *maxrss = rusage.ru_maxrss * 1024; // ru_maxrss is in kB
        return 0;
#else
        return get_error_errno();
#endif
    }
    int r = ENOENT;
    char line[100];
    while (fgets(line, sizeof line, f)) {
        r = sscanf(line, "VmHWM:\t%lld kB\n", (long long *) maxrss);
        if (r == 1) {
            *maxrss *= 1<<10;
            r = 0;
            break;
        }
    }
    fclose(f);
    return r;
}

int
toku_os_get_rss(int64_t *rss) {
    char statusname[100];
    sprintf(statusname, "/proc/%d/status", getpid());
    FILE *f = fopen(statusname, "r");
    if (f == NULL) {
#if defined(HAVE_SYS_RESOURCE_H)
        // try getrusage instead
        struct rusage rusage;
        getrusage(RUSAGE_SELF, &rusage);
        *rss = (rusage.ru_idrss + rusage.ru_ixrss + rusage.ru_isrss) * 1024;
        return 0;
#else
        return get_error_errno();
#endif
    }
    int r = ENOENT;
    char line[100];
    while (fgets(line, sizeof line, f)) {
        r = sscanf(line, "VmRSS:\t%lld kB\n", (long long *) rss);
        if (r == 1) {
            *rss *= 1<<10;
            r = 0;
            break;
        }
    }
    fclose(f);
    return r;
}

bool toku_os_is_absolute_name(const char* path) {
    return path[0] == '/';
}

int
toku_os_get_max_process_data_size(uint64_t *maxdata) {
    int r;
    struct rlimit rlimit;

    r = getrlimit(RLIMIT_DATA, &rlimit);
    if (r == 0) {
        uint64_t d;
        d = rlimit.rlim_max;
	// with the "right" macros defined, the rlimit is a 64 bit number on a
	// 32 bit system.  getrlimit returns 2**64-1 which is clearly wrong.

        // for 32 bit processes, we assume that 1/2 of the address space is
        // used for mapping the kernel.  this may be pessimistic.
        if (sizeof (void *) == 4 && d > (1ULL << 31))
            d = 1ULL << 31;
	*maxdata = d;
    } else
        r = get_error_errno();
    return r;
}

int
toku_stat(const char *name, toku_struct_stat *buf) {
    int r = stat(name, buf);
    return r;
}

int
toku_fstat(int fd, toku_struct_stat *buf) {
    int r = fstat(fd, buf);
    return r;
}

static int
toku_get_processor_frequency_sys(uint64_t *hzret) {
    int r;
    FILE *fp = fopen("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", "r");
    if (!fp)
        r = get_error_errno();
    else {
        unsigned int khz = 0;
        if (fscanf(fp, "%u", &khz) == 1) {
            *hzret = khz * 1000ULL;
            r = 0;
        } else
            r = ENOENT;
        fclose(fp);
    }
    return r;
}

static int
toku_get_processor_frequency_cpuinfo(uint64_t *hzret) {
    int r;
    FILE *fp = fopen("/proc/cpuinfo", "r");
    if (!fp) {
        r = get_error_errno();
    } else {
        uint64_t maxhz = 0;
        char *buf = NULL;
        size_t n = 0;
        while (getline(&buf, &n, fp) >= 0) {
            unsigned int cpu;
            sscanf(buf, "processor : %u", &cpu);
            unsigned int ma, mb;
            if (sscanf(buf, "cpu MHz : %u.%u", &ma, &mb) == 2) {
                uint64_t hz = ma * 1000000ULL + mb * 1000ULL;
                if (hz > maxhz)
                    maxhz = hz;
            }
        }
        if (buf)
            free(buf);
        fclose(fp);
        *hzret = maxhz;
        r = maxhz == 0 ? ENOENT : 0;;
    }
    return r;
}

static int
toku_get_processor_frequency_sysctl(uint64_t *hzret) {
    int r = 0;
    static char cmd[] = "sysctl hw.cpufrequency";
    FILE *fp = popen(cmd, "r");
    if (!fp) {
        r = EINVAL;  // popen doesn't return anything useful in errno,
                     // gotta pick something
        goto exit;
    }
    r = fscanf(fp, "hw.cpufrequency: %" SCNu64, hzret);
    if (r != 1) {
        r = get_maybe_error_errno();
    } else {
        r = 0;
    }

exit:
    return r;
}

int
toku_os_get_processor_frequency(uint64_t *hzret) {
    int r;
    r = toku_get_processor_frequency_sys(hzret);
    if (r != 0)
        r = toku_get_processor_frequency_cpuinfo(hzret);
    if (r != 0)
        r = toku_get_processor_frequency_sysctl(hzret);
    return r;
}

int
toku_get_filesystem_sizes(const char *path, uint64_t *avail_size, uint64_t *free_size, uint64_t *total_size) {
    struct statvfs s;
    int r = statvfs(path, &s);
    if (r == -1) {
        r = get_error_errno();
    } else {
        // get the block size in bytes
        uint64_t bsize = s.f_frsize ? s.f_frsize : s.f_bsize;
        // convert blocks to bytes
        if (avail_size)
            *avail_size = (uint64_t) s.f_bavail * bsize;
        if (free_size)
            *free_size = (uint64_t) s.f_bfree * bsize;
        if (total_size)
            *total_size = (uint64_t) s.f_blocks * bsize;
    }
    return r;
}

int
toku_dup2(int fd, int fd2) {
    int r;
    r = dup2(fd, fd2);
    return r;
}

// Time
static       double seconds_per_clock = -1;

double tokutime_to_seconds(tokutime_t t) {
    // Convert tokutime to seconds.
    if (seconds_per_clock<0) {
	uint64_t hz;
	int r = toku_os_get_processor_frequency(&hz);
	assert(r==0);
	// There's a race condition here, but it doesn't really matter.  If two threads call tokutime_to_seconds
	// for the first time at the same time, then both will fetch the value and set the same value.
	seconds_per_clock = 1.0/hz;
    }
    return t*seconds_per_clock;
}

#if __GNUC__ && __i386__

// workaround for a gcc 4.1.2 bug on 32 bit platforms.
uint64_t toku_sync_fetch_and_add_uint64(volatile uint64_t *a, uint64_t b) __attribute__((noinline));

uint64_t toku_sync_fetch_and_add_uint64(volatile uint64_t *a, uint64_t b) {
    return __sync_fetch_and_add(a, b);
}

#endif
<commit_msg>refs #5508 remove cpu affinity code that calculates the number of processors from the portability layer<commit_after>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#ident "Copyright (c) 2007-2012 Tokutek Inc.  All rights reserved."
#ident "$Id$"

#include <config.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <toku_assert.h>
#if defined(HAVE_MALLOC_H)
# include <malloc.h>
#elif defined(HAVE_SYS_MALLOC_H)
# include <sys/malloc.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#if defined(HAVE_SYSCALL_H)
# include <syscall.h>
#elif defined(HAVE_SYS_SYSCALL_H)
# include <sys/syscall.h>
# if !defined(__NR_gettid) && defined(SYS_gettid)
#  define __NR_gettid SYS_gettid
# endif
#endif
#if defined(HAVE_SYS_SYSCTL_H)
# include <sys/sysctl.h>
#endif
#include <inttypes.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/statvfs.h>
#include "toku_portability.h"
#include "toku_os.h"
#include "toku_time.h"
#include "memory.h"

int
toku_portability_init(void) {
    int r = toku_memory_startup();
    return r;
}

void
toku_portability_destroy(void) {
    toku_memory_shutdown();
}

int
toku_os_getpid(void) {
    return getpid();
}

int
toku_os_gettid(void) {
    return syscall(__NR_gettid);
}

int
toku_os_get_number_processors(void) {
    return sysconf(_SC_NPROCESSORS_CONF);
}

int
toku_os_get_number_active_processors(void) {
    int n = sysconf(_SC_NPROCESSORS_ONLN);
#define DO_TOKU_NCPUS 1
#if DO_TOKU_NCPUS
    {
        char *toku_ncpus = getenv("TOKU_NCPUS");
        if (toku_ncpus) {
            int ncpus = atoi(toku_ncpus);
            if (ncpus < n)
                n = ncpus;
        }
    }
#endif
    return n;
}

int
toku_os_get_pagesize(void) {
    return sysconf(_SC_PAGESIZE);
}

uint64_t
toku_os_get_phys_memory_size(void) {
#if defined(_SC_PHYS_PAGES)
    uint64_t npages = sysconf(_SC_PHYS_PAGES);
    uint64_t pagesize = sysconf(_SC_PAGESIZE);
    return npages*pagesize;
#elif defined(HAVE_SYS_SYSCTL_H)
    uint64_t memsize;
    size_t len = sizeof memsize;
    sysctlbyname("hw.memsize", &memsize, &len, NULL, 0);
    return memsize;
#else
# error "cannot find _SC_PHYS_PAGES or sysctlbyname()"
#endif
}

int
toku_os_get_file_size(int fildes, int64_t *fsize) {
    toku_struct_stat sbuf;
    int r = fstat(fildes, &sbuf);
    if (r==0) {
        *fsize = sbuf.st_size;
    }
    return r;
}

int
toku_os_get_unique_file_id(int fildes, struct fileid *id) {
    toku_struct_stat statbuf;
    memset(id, 0, sizeof(*id));
    int r=fstat(fildes, &statbuf);
    if (r==0) {
        id->st_dev = statbuf.st_dev;
        id->st_ino = statbuf.st_ino;
    }
    return r;
}

int
toku_os_lock_file(const char *name) {
    int r;
    int fd = open(name, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR);
    if (fd>=0) {
        r = flock(fd, LOCK_EX | LOCK_NB);
        if (r!=0) {
            r = errno; //Save errno from flock.
            close(fd);
            fd = -1; //Disable fd.
            errno = r;
        }
    }
    return fd;
}

int
toku_os_unlock_file(int fildes) {
    int r = flock(fildes, LOCK_UN);
    if (r==0) r = close(fildes);
    return r;
}

int
toku_os_mkdir(const char *pathname, mode_t mode) {
    int r = mkdir(pathname, mode);
    return r;
}

int
toku_os_get_process_times(struct timeval *usertime, struct timeval *kerneltime) {
    int r;
    struct rusage rusage;
    r = getrusage(RUSAGE_SELF, &rusage);
    if (r == -1)
        return get_error_errno();
    if (usertime)
        *usertime = rusage.ru_utime;
    if (kerneltime)
        *kerneltime = rusage.ru_stime;
    return 0;
}

int
toku_os_initialize_settings(int UU(verbosity)) {
    int r = 0;
    static int initialized = 0;
    assert(initialized==0);
    initialized=1;
    return r;
}

int
toku_os_get_max_rss(int64_t *maxrss) {
    char statusname[100];
    sprintf(statusname, "/proc/%d/status", getpid());
    FILE *f = fopen(statusname, "r");
    if (f == NULL) {
#if defined(HAVE_SYS_RESOURCE_H)
        // try getrusage instead
        struct rusage rusage;
        getrusage(RUSAGE_SELF, &rusage);
        *maxrss = rusage.ru_maxrss * 1024; // ru_maxrss is in kB
        return 0;
#else
        return get_error_errno();
#endif
    }
    int r = ENOENT;
    char line[100];
    while (fgets(line, sizeof line, f)) {
        r = sscanf(line, "VmHWM:\t%lld kB\n", (long long *) maxrss);
        if (r == 1) {
            *maxrss *= 1<<10;
            r = 0;
            break;
        }
    }
    fclose(f);
    return r;
}

int
toku_os_get_rss(int64_t *rss) {
    char statusname[100];
    sprintf(statusname, "/proc/%d/status", getpid());
    FILE *f = fopen(statusname, "r");
    if (f == NULL) {
#if defined(HAVE_SYS_RESOURCE_H)
        // try getrusage instead
        struct rusage rusage;
        getrusage(RUSAGE_SELF, &rusage);
        *rss = (rusage.ru_idrss + rusage.ru_ixrss + rusage.ru_isrss) * 1024;
        return 0;
#else
        return get_error_errno();
#endif
    }
    int r = ENOENT;
    char line[100];
    while (fgets(line, sizeof line, f)) {
        r = sscanf(line, "VmRSS:\t%lld kB\n", (long long *) rss);
        if (r == 1) {
            *rss *= 1<<10;
            r = 0;
            break;
        }
    }
    fclose(f);
    return r;
}

bool toku_os_is_absolute_name(const char* path) {
    return path[0] == '/';
}

int
toku_os_get_max_process_data_size(uint64_t *maxdata) {
    int r;
    struct rlimit rlimit;

    r = getrlimit(RLIMIT_DATA, &rlimit);
    if (r == 0) {
        uint64_t d;
        d = rlimit.rlim_max;
	// with the "right" macros defined, the rlimit is a 64 bit number on a
	// 32 bit system.  getrlimit returns 2**64-1 which is clearly wrong.

        // for 32 bit processes, we assume that 1/2 of the address space is
        // used for mapping the kernel.  this may be pessimistic.
        if (sizeof (void *) == 4 && d > (1ULL << 31))
            d = 1ULL << 31;
	*maxdata = d;
    } else
        r = get_error_errno();
    return r;
}

int
toku_stat(const char *name, toku_struct_stat *buf) {
    int r = stat(name, buf);
    return r;
}

int
toku_fstat(int fd, toku_struct_stat *buf) {
    int r = fstat(fd, buf);
    return r;
}

static int
toku_get_processor_frequency_sys(uint64_t *hzret) {
    int r;
    FILE *fp = fopen("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", "r");
    if (!fp)
        r = get_error_errno();
    else {
        unsigned int khz = 0;
        if (fscanf(fp, "%u", &khz) == 1) {
            *hzret = khz * 1000ULL;
            r = 0;
        } else
            r = ENOENT;
        fclose(fp);
    }
    return r;
}

static int
toku_get_processor_frequency_cpuinfo(uint64_t *hzret) {
    int r;
    FILE *fp = fopen("/proc/cpuinfo", "r");
    if (!fp) {
        r = get_error_errno();
    } else {
        uint64_t maxhz = 0;
        char *buf = NULL;
        size_t n = 0;
        while (getline(&buf, &n, fp) >= 0) {
            unsigned int cpu;
            sscanf(buf, "processor : %u", &cpu);
            unsigned int ma, mb;
            if (sscanf(buf, "cpu MHz : %u.%u", &ma, &mb) == 2) {
                uint64_t hz = ma * 1000000ULL + mb * 1000ULL;
                if (hz > maxhz)
                    maxhz = hz;
            }
        }
        if (buf)
            free(buf);
        fclose(fp);
        *hzret = maxhz;
        r = maxhz == 0 ? ENOENT : 0;;
    }
    return r;
}

static int
toku_get_processor_frequency_sysctl(uint64_t *hzret) {
    int r = 0;
    static char cmd[] = "sysctl hw.cpufrequency";
    FILE *fp = popen(cmd, "r");
    if (!fp) {
        r = EINVAL;  // popen doesn't return anything useful in errno,
                     // gotta pick something
        goto exit;
    }
    r = fscanf(fp, "hw.cpufrequency: %" SCNu64, hzret);
    if (r != 1) {
        r = get_maybe_error_errno();
    } else {
        r = 0;
    }

exit:
    return r;
}

int
toku_os_get_processor_frequency(uint64_t *hzret) {
    int r;
    r = toku_get_processor_frequency_sys(hzret);
    if (r != 0)
        r = toku_get_processor_frequency_cpuinfo(hzret);
    if (r != 0)
        r = toku_get_processor_frequency_sysctl(hzret);
    return r;
}

int
toku_get_filesystem_sizes(const char *path, uint64_t *avail_size, uint64_t *free_size, uint64_t *total_size) {
    struct statvfs s;
    int r = statvfs(path, &s);
    if (r == -1) {
        r = get_error_errno();
    } else {
        // get the block size in bytes
        uint64_t bsize = s.f_frsize ? s.f_frsize : s.f_bsize;
        // convert blocks to bytes
        if (avail_size)
            *avail_size = (uint64_t) s.f_bavail * bsize;
        if (free_size)
            *free_size = (uint64_t) s.f_bfree * bsize;
        if (total_size)
            *total_size = (uint64_t) s.f_blocks * bsize;
    }
    return r;
}

int
toku_dup2(int fd, int fd2) {
    int r;
    r = dup2(fd, fd2);
    return r;
}

// Time
static       double seconds_per_clock = -1;

double tokutime_to_seconds(tokutime_t t) {
    // Convert tokutime to seconds.
    if (seconds_per_clock<0) {
	uint64_t hz;
	int r = toku_os_get_processor_frequency(&hz);
	assert(r==0);
	// There's a race condition here, but it doesn't really matter.  If two threads call tokutime_to_seconds
	// for the first time at the same time, then both will fetch the value and set the same value.
	seconds_per_clock = 1.0/hz;
    }
    return t*seconds_per_clock;
}

#if __GNUC__ && __i386__

// workaround for a gcc 4.1.2 bug on 32 bit platforms.
uint64_t toku_sync_fetch_and_add_uint64(volatile uint64_t *a, uint64_t b) __attribute__((noinline));

uint64_t toku_sync_fetch_and_add_uint64(volatile uint64_t *a, uint64_t b) {
    return __sync_fetch_and_add(a, b);
}

#endif
<|endoftext|>


<commit_before>//===- PowerPCRegisterInfo.cpp - PowerPC Register Information ---*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the MRegisterInfo class.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "reginfo"
#include "PowerPC.h"
#include "PowerPCRegisterInfo.h"
#include "PowerPCInstrBuilder.h"
#include "llvm/Constants.h"
#include "llvm/Type.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "Support/CommandLine.h"
#include "Support/Debug.h"
#include "Support/STLExtras.h"
#include <iostream>
using namespace llvm;

namespace llvm {
  // Switch toggling compilation for AIX
  extern cl::opt<bool> AIX;
}

PowerPCRegisterInfo::PowerPCRegisterInfo(bool is64b)
  : PowerPCGenRegisterInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP),
    is64bit(is64b) {
  ImmToIdxMap[PPC::LD]   = PPC::LDX;    ImmToIdxMap[PPC::STD]  = PPC::STDX;
  ImmToIdxMap[PPC::LBZ]  = PPC::LBZX;   ImmToIdxMap[PPC::STB]  = PPC::STBX;
  ImmToIdxMap[PPC::LHZ]  = PPC::LHZX;   ImmToIdxMap[PPC::LHA]  = PPC::LHAX;
  ImmToIdxMap[PPC::LWZ]  = PPC::LWZX;   ImmToIdxMap[PPC::LWA]  = PPC::LWAX;
  ImmToIdxMap[PPC::LFS]  = PPC::LFSX;   ImmToIdxMap[PPC::LFD]  = PPC::LFDX;
  ImmToIdxMap[PPC::STH]  = PPC::STHX;   ImmToIdxMap[PPC::STW]  = PPC::STWX;
  ImmToIdxMap[PPC::STFS] = PPC::STFSX;  ImmToIdxMap[PPC::STFD] = PPC::STFDX;
  ImmToIdxMap[PPC::ADDI] = PPC::ADD;
}

static unsigned getIdx(const TargetRegisterClass *RC) {
  if (RC == PowerPC::GPRCRegisterClass) {
    switch (RC->getSize()) {
      default: assert(0 && "Invalid data size!");
      case 1:  return 0;
      case 2:  return 1;
      case 4:  return 2;
      case 8:  return 3;
    }
  } else if (RC == PowerPC::FPRCRegisterClass) {
    switch (RC->getSize()) {
      default: assert(0 && "Invalid data size!");
      case 4:  return 4;
      case 8:  return 5;
    }
  }
  std::cerr << "Invalid register class to getIdx()!\n";
  abort();
}

void
PowerPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
                                         MachineBasicBlock::iterator MI,
                                         unsigned SrcReg, int FrameIdx) const {
  const TargetRegisterClass *RC = getRegClass(SrcReg);
  static const unsigned Opcode[] = {
    PPC::STB, PPC::STH, PPC::STW, PPC::STD, PPC::STFS, PPC::STFD
  };

  unsigned OC = Opcode[getIdx(RC)];
  if (SrcReg == PPC::LR) {
    BuildMI(MBB, MI, PPC::MFLR, 0, PPC::R11);
    BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0);
    addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(PPC::R11),FrameIdx);
  } else {
    BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0);
    addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(SrcReg),FrameIdx);
  }
}

void
PowerPCRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
                                          MachineBasicBlock::iterator MI,
                                          unsigned DestReg, int FrameIdx) const{
  static const unsigned Opcode[] = {
    PPC::LBZ, PPC::LHZ, PPC::LWZ, PPC::LD, PPC::LFS, PPC::LFD
  };
  const TargetRegisterClass *RC = getRegClass(DestReg);
  unsigned OC = Opcode[getIdx(RC)];
  if (DestReg == PPC::LR) {
    BuildMI(MBB, MI, PPC::IMPLCICIT_DEF, 0, PPC::R0);
    addFrameReference(BuildMI(MBB, MI, OC, 2, PPC::R11), FrameIdx);
    BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11);
  } else {
    BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0);
    addFrameReference(BuildMI(MBB, MI, OC, 2, DestReg), FrameIdx);
  }
}

void PowerPCRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
                                       MachineBasicBlock::iterator MI,
                                       unsigned DestReg, unsigned SrcReg,
                                       const TargetRegisterClass *RC) const {
  MachineInstr *I;

  if (RC == PowerPC::GPRCRegisterClass) {
    BuildMI(MBB, MI, PPC::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
  } else if (RC == PowerPC::FPRCRegisterClass) {
    BuildMI(MBB, MI, PPC::FMR, 1, DestReg).addReg(SrcReg);
  } else {
    std::cerr << "Attempt to copy register that is not GPR or FPR";
    abort();
  }
}

//===----------------------------------------------------------------------===//
// Stack Frame Processing methods
//===----------------------------------------------------------------------===//

// hasFP - Return true if the specified function should have a dedicated frame
// pointer register.  This is true if the function has variable sized allocas or
// if frame pointer elimination is disabled.
//
static bool hasFP(MachineFunction &MF) {
  MachineFrameInfo *MFI = MF.getFrameInfo();
  return MFI->hasVarSizedObjects();
}

void PowerPCRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
                              MachineBasicBlock::iterator I) const {
  if (hasFP(MF)) {
    // If we have a frame pointer, convert as follows:
    // ADJCALLSTACKDOWN -> addi, r1, r1, -amount
    // ADJCALLSTACKUP   -> addi, r1, r1, amount
    MachineInstr *Old = I;
    unsigned Amount = Old->getOperand(0).getImmedValue();
    if (Amount != 0) {
      // We need to keep the stack aligned properly.  To do this, we round the
      // amount of space needed for the outgoing arguments up to the next
      // alignment boundary.
      unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
      Amount = (Amount+Align-1)/Align*Align;

      // Replace the pseudo instruction with a new instruction...
      if (Old->getOpcode() == PPC::ADJCALLSTACKDOWN) {
        MBB.insert(I, BuildMI(PPC::ADDI, 2, PPC::R1).addReg(PPC::R1)
                .addSImm(-Amount));
      } else {
        assert(Old->getOpcode() == PPC::ADJCALLSTACKUP);
        MBB.insert(I, BuildMI(PPC::ADDI, 2, PPC::R1).addReg(PPC::R1)
                .addSImm(Amount));
      }
    }
  }
  MBB.erase(I);
}

void
PowerPCRegisterInfo::
eliminateFrameIndex(MachineBasicBlock::iterator II) const {
  unsigned i = 0;
  MachineInstr &MI = *II;
  MachineBasicBlock &MBB = *MI.getParent();
  MachineFunction &MF = *MBB.getParent();

  while (!MI.getOperand(i).isFrameIndex()) {
    ++i;
    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
  }

  int FrameIndex = MI.getOperand(i).getFrameIndex();

  // Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP).
  MI.SetMachineOperandReg(i, hasFP(MF) ? PPC::R31 : PPC::R1);

  // Take into account whether it's an add or mem instruction
  unsigned OffIdx = (i == 2) ? 1 : 2;

  // Now add the frame object offset to the offset from r1.
  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
               MI.getOperand(OffIdx).getImmedValue();

  // If we're not using a Frame Pointer that has been set to the value of the
  // SP before having the stack size subtracted from it, then add the stack size
  // to Offset to get the correct offset.
  Offset += MF.getFrameInfo()->getStackSize();

  if (Offset > 32767 || Offset < -32768) {
    // Insert a set of r0 with the full offset value before the ld, st, or add
    MachineBasicBlock *MBB = MI.getParent();
    MBB->insert(II, BuildMI(PPC::LIS, 1, PPC::R0).addSImm(Offset >> 16));
    MBB->insert(II, BuildMI(PPC::ORI, 2, PPC::R0).addReg(PPC::R0)
      .addImm(Offset));
    // convert into indexed form of the instruction
    // sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0
    // addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0
    unsigned NewOpcode = const_cast<std::map<unsigned, unsigned>& >(ImmToIdxMap)[MI.getOpcode()];
    assert(NewOpcode && "No indexed form of load or store available!");
    MI.setOpcode(NewOpcode);
    MI.SetMachineOperandReg(1, MI.getOperand(i).getReg());
    MI.SetMachineOperandReg(2, PPC::R0);
  } else {
    MI.SetMachineOperandConst(OffIdx,MachineOperand::MO_SignExtendedImmed,Offset);
  }
}

void PowerPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
  MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
  MachineBasicBlock::iterator MBBI = MBB.begin();
  MachineFrameInfo *MFI = MF.getFrameInfo();
  MachineInstr *MI;

  // Get the number of bytes to allocate from the FrameInfo
  unsigned NumBytes = MFI->getStackSize();

  // If we have calls, we cannot use the red zone to store callee save registers
  // and we must set up a stack frame, so calculate the necessary size here.
  if (MFI->hasCalls()) {
    // We reserve argument space for call sites in the function immediately on
    // entry to the current function.  This eliminates the need for add/sub
    // brackets around call sites.
    NumBytes += MFI->getMaxCallFrameSize();
  }

  // Do we need to allocate space on the stack?
  if (NumBytes == 0) return;

  // Add the size of R1 to  NumBytes size for the store of R1 to the bottom
  // of the stack and round the size to a multiple of the alignment.
  unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
  unsigned R1Size = getRegClass(PPC::R1)->getSize();
  unsigned R31Size = getRegClass(PPC::R31)->getSize();
  unsigned Size = (hasFP(MF)) ? R1Size + R31Size : R1Size;
  NumBytes = (NumBytes+Size+Align-1)/Align*Align;

  // Update frame info to pretend that this is part of the stack...
  MFI->setStackSize(NumBytes);

  // adjust stack pointer: r1 -= numbytes
  if (NumBytes <= 32768) {
    unsigned StoreOp = is64bit ? PPC::STDU : PPC::STWU;
    MI = BuildMI(StoreOp, 3).addReg(PPC::R1).addSImm(-NumBytes).addReg(PPC::R1);
    MBB.insert(MBBI, MI);
  } else {
    int NegNumbytes = -NumBytes;
    unsigned StoreOp = is64bit ? PPC::STDUX : PPC::STWUX;
    MI = BuildMI(PPC::LIS, 1, PPC::R0).addSImm(NegNumbytes >> 16);
    MBB.insert(MBBI, MI);
    MI = BuildMI(PPC::ORI, 2, PPC::R0).addReg(PPC::R0)
      .addImm(NegNumbytes & 0xFFFF);
    MBB.insert(MBBI, MI);
    MI = BuildMI(StoreOp, 3).addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0);
    MBB.insert(MBBI, MI);
  }

  if (hasFP(MF)) {
    unsigned StoreOp = is64bit ? PPC::STD : PPC::STW;
    MI = BuildMI(StoreOp, 3).addReg(PPC::R31).addSImm(R1Size).addReg(PPC::R1);
    MBB.insert(MBBI, MI);
    MI = BuildMI(PPC::OR, 2, PPC::R31).addReg(PPC::R1).addReg(PPC::R1);
    MBB.insert(MBBI, MI);
  }
}

void PowerPCRegisterInfo::emitEpilogue(MachineFunction &MF,
                                       MachineBasicBlock &MBB) const {
  const MachineFrameInfo *MFI = MF.getFrameInfo();
  MachineBasicBlock::iterator MBBI = prior(MBB.end());
  MachineInstr *MI;
  assert(MBBI->getOpcode() == PPC::BLR &&
         "Can only insert epilog into returning blocks");

  // Get the number of bytes allocated from the FrameInfo...
  unsigned NumBytes = MFI->getStackSize();

  if (NumBytes != 0) {
    unsigned Opcode = is64bit ? PPC::LD : PPC::LWZ;
    unsigned Offset = is64bit ? 8 : 4;
    if (hasFP(MF)) {
      MI = BuildMI(PPC::OR, 2, PPC::R1).addReg(PPC::R31).addReg(PPC::R31);
      MBB.insert(MBBI, MI);
      MI = BuildMI(Opcode, 2, PPC::R31).addSImm(Offset).addReg(PPC::R31);
      MBB.insert(MBBI, MI);
    }
    MI = BuildMI(Opcode, 2, PPC::R1).addSImm(0).addReg(PPC::R1);
    MBB.insert(MBBI, MI);
  }
}

#include "PowerPCGenRegisterInfo.inc"

const TargetRegisterClass*
PowerPCRegisterInfo::getRegClassForType(const Type* Ty) const {
  switch (Ty->getTypeID()) {
    default:              assert(0 && "Invalid type to getClass!");
    case Type::LongTyID:
    case Type::ULongTyID:
      if (!is64bit) assert(0 && "Long values can't fit in registers!");
    case Type::BoolTyID:
    case Type::SByteTyID:
    case Type::UByteTyID:
    case Type::ShortTyID:
    case Type::UShortTyID:
    case Type::IntTyID:
    case Type::UIntTyID:
    case Type::PointerTyID: return &GPRCInstance;

    case Type::FloatTyID:
    case Type::DoubleTyID: return &FPRCInstance;
  }
}

<commit_msg>Fix typo of the word 'implicit' I made resolving a CVS conflict.  Whoops!<commit_after>//===- PowerPCRegisterInfo.cpp - PowerPC Register Information ---*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the MRegisterInfo class.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "reginfo"
#include "PowerPC.h"
#include "PowerPCRegisterInfo.h"
#include "PowerPCInstrBuilder.h"
#include "llvm/Constants.h"
#include "llvm/Type.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "Support/CommandLine.h"
#include "Support/Debug.h"
#include "Support/STLExtras.h"
#include <iostream>
using namespace llvm;

namespace llvm {
  // Switch toggling compilation for AIX
  extern cl::opt<bool> AIX;
}

PowerPCRegisterInfo::PowerPCRegisterInfo(bool is64b)
  : PowerPCGenRegisterInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP),
    is64bit(is64b) {
  ImmToIdxMap[PPC::LD]   = PPC::LDX;    ImmToIdxMap[PPC::STD]  = PPC::STDX;
  ImmToIdxMap[PPC::LBZ]  = PPC::LBZX;   ImmToIdxMap[PPC::STB]  = PPC::STBX;
  ImmToIdxMap[PPC::LHZ]  = PPC::LHZX;   ImmToIdxMap[PPC::LHA]  = PPC::LHAX;
  ImmToIdxMap[PPC::LWZ]  = PPC::LWZX;   ImmToIdxMap[PPC::LWA]  = PPC::LWAX;
  ImmToIdxMap[PPC::LFS]  = PPC::LFSX;   ImmToIdxMap[PPC::LFD]  = PPC::LFDX;
  ImmToIdxMap[PPC::STH]  = PPC::STHX;   ImmToIdxMap[PPC::STW]  = PPC::STWX;
  ImmToIdxMap[PPC::STFS] = PPC::STFSX;  ImmToIdxMap[PPC::STFD] = PPC::STFDX;
  ImmToIdxMap[PPC::ADDI] = PPC::ADD;
}

static unsigned getIdx(const TargetRegisterClass *RC) {
  if (RC == PowerPC::GPRCRegisterClass) {
    switch (RC->getSize()) {
      default: assert(0 && "Invalid data size!");
      case 1:  return 0;
      case 2:  return 1;
      case 4:  return 2;
      case 8:  return 3;
    }
  } else if (RC == PowerPC::FPRCRegisterClass) {
    switch (RC->getSize()) {
      default: assert(0 && "Invalid data size!");
      case 4:  return 4;
      case 8:  return 5;
    }
  }
  std::cerr << "Invalid register class to getIdx()!\n";
  abort();
}

void
PowerPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
                                         MachineBasicBlock::iterator MI,
                                         unsigned SrcReg, int FrameIdx) const {
  const TargetRegisterClass *RC = getRegClass(SrcReg);
  static const unsigned Opcode[] = {
    PPC::STB, PPC::STH, PPC::STW, PPC::STD, PPC::STFS, PPC::STFD
  };

  unsigned OC = Opcode[getIdx(RC)];
  if (SrcReg == PPC::LR) {
    BuildMI(MBB, MI, PPC::MFLR, 0, PPC::R11);
    BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0);
    addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(PPC::R11),FrameIdx);
  } else {
    BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0);
    addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(SrcReg),FrameIdx);
  }
}

void
PowerPCRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
                                          MachineBasicBlock::iterator MI,
                                          unsigned DestReg, int FrameIdx) const{
  static const unsigned Opcode[] = {
    PPC::LBZ, PPC::LHZ, PPC::LWZ, PPC::LD, PPC::LFS, PPC::LFD
  };
  const TargetRegisterClass *RC = getRegClass(DestReg);
  unsigned OC = Opcode[getIdx(RC)];
  if (DestReg == PPC::LR) {
    BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0);
    addFrameReference(BuildMI(MBB, MI, OC, 2, PPC::R11), FrameIdx);
    BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11);
  } else {
    BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0);
    addFrameReference(BuildMI(MBB, MI, OC, 2, DestReg), FrameIdx);
  }
}

void PowerPCRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
                                       MachineBasicBlock::iterator MI,
                                       unsigned DestReg, unsigned SrcReg,
                                       const TargetRegisterClass *RC) const {
  MachineInstr *I;

  if (RC == PowerPC::GPRCRegisterClass) {
    BuildMI(MBB, MI, PPC::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
  } else if (RC == PowerPC::FPRCRegisterClass) {
    BuildMI(MBB, MI, PPC::FMR, 1, DestReg).addReg(SrcReg);
  } else {
    std::cerr << "Attempt to copy register that is not GPR or FPR";
    abort();
  }
}

//===----------------------------------------------------------------------===//
// Stack Frame Processing methods
//===----------------------------------------------------------------------===//

// hasFP - Return true if the specified function should have a dedicated frame
// pointer register.  This is true if the function has variable sized allocas or
// if frame pointer elimination is disabled.
//
static bool hasFP(MachineFunction &MF) {
  MachineFrameInfo *MFI = MF.getFrameInfo();
  return MFI->hasVarSizedObjects();
}

void PowerPCRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
                              MachineBasicBlock::iterator I) const {
  if (hasFP(MF)) {
    // If we have a frame pointer, convert as follows:
    // ADJCALLSTACKDOWN -> addi, r1, r1, -amount
    // ADJCALLSTACKUP   -> addi, r1, r1, amount
    MachineInstr *Old = I;
    unsigned Amount = Old->getOperand(0).getImmedValue();
    if (Amount != 0) {
      // We need to keep the stack aligned properly.  To do this, we round the
      // amount of space needed for the outgoing arguments up to the next
      // alignment boundary.
      unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
      Amount = (Amount+Align-1)/Align*Align;

      // Replace the pseudo instruction with a new instruction...
      if (Old->getOpcode() == PPC::ADJCALLSTACKDOWN) {
        MBB.insert(I, BuildMI(PPC::ADDI, 2, PPC::R1).addReg(PPC::R1)
                .addSImm(-Amount));
      } else {
        assert(Old->getOpcode() == PPC::ADJCALLSTACKUP);
        MBB.insert(I, BuildMI(PPC::ADDI, 2, PPC::R1).addReg(PPC::R1)
                .addSImm(Amount));
      }
    }
  }
  MBB.erase(I);
}

void
PowerPCRegisterInfo::
eliminateFrameIndex(MachineBasicBlock::iterator II) const {
  unsigned i = 0;
  MachineInstr &MI = *II;
  MachineBasicBlock &MBB = *MI.getParent();
  MachineFunction &MF = *MBB.getParent();

  while (!MI.getOperand(i).isFrameIndex()) {
    ++i;
    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
  }

  int FrameIndex = MI.getOperand(i).getFrameIndex();

  // Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP).
  MI.SetMachineOperandReg(i, hasFP(MF) ? PPC::R31 : PPC::R1);

  // Take into account whether it's an add or mem instruction
  unsigned OffIdx = (i == 2) ? 1 : 2;

  // Now add the frame object offset to the offset from r1.
  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
               MI.getOperand(OffIdx).getImmedValue();

  // If we're not using a Frame Pointer that has been set to the value of the
  // SP before having the stack size subtracted from it, then add the stack size
  // to Offset to get the correct offset.
  Offset += MF.getFrameInfo()->getStackSize();

  if (Offset > 32767 || Offset < -32768) {
    // Insert a set of r0 with the full offset value before the ld, st, or add
    MachineBasicBlock *MBB = MI.getParent();
    MBB->insert(II, BuildMI(PPC::LIS, 1, PPC::R0).addSImm(Offset >> 16));
    MBB->insert(II, BuildMI(PPC::ORI, 2, PPC::R0).addReg(PPC::R0)
      .addImm(Offset));
    // convert into indexed form of the instruction
    // sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0
    // addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0
    unsigned NewOpcode = const_cast<std::map<unsigned, unsigned>& >(ImmToIdxMap)[MI.getOpcode()];
    assert(NewOpcode && "No indexed form of load or store available!");
    MI.setOpcode(NewOpcode);
    MI.SetMachineOperandReg(1, MI.getOperand(i).getReg());
    MI.SetMachineOperandReg(2, PPC::R0);
  } else {
    MI.SetMachineOperandConst(OffIdx,MachineOperand::MO_SignExtendedImmed,Offset);
  }
}

void PowerPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
  MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
  MachineBasicBlock::iterator MBBI = MBB.begin();
  MachineFrameInfo *MFI = MF.getFrameInfo();
  MachineInstr *MI;

  // Get the number of bytes to allocate from the FrameInfo
  unsigned NumBytes = MFI->getStackSize();

  // If we have calls, we cannot use the red zone to store callee save registers
  // and we must set up a stack frame, so calculate the necessary size here.
  if (MFI->hasCalls()) {
    // We reserve argument space for call sites in the function immediately on
    // entry to the current function.  This eliminates the need for add/sub
    // brackets around call sites.
    NumBytes += MFI->getMaxCallFrameSize();
  }

  // Do we need to allocate space on the stack?
  if (NumBytes == 0) return;

  // Add the size of R1 to  NumBytes size for the store of R1 to the bottom
  // of the stack and round the size to a multiple of the alignment.
  unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
  unsigned R1Size = getRegClass(PPC::R1)->getSize();
  unsigned R31Size = getRegClass(PPC::R31)->getSize();
  unsigned Size = (hasFP(MF)) ? R1Size + R31Size : R1Size;
  NumBytes = (NumBytes+Size+Align-1)/Align*Align;

  // Update frame info to pretend that this is part of the stack...
  MFI->setStackSize(NumBytes);

  // adjust stack pointer: r1 -= numbytes
  if (NumBytes <= 32768) {
    unsigned StoreOp = is64bit ? PPC::STDU : PPC::STWU;
    MI = BuildMI(StoreOp, 3).addReg(PPC::R1).addSImm(-NumBytes).addReg(PPC::R1);
    MBB.insert(MBBI, MI);
  } else {
    int NegNumbytes = -NumBytes;
    unsigned StoreOp = is64bit ? PPC::STDUX : PPC::STWUX;
    MI = BuildMI(PPC::LIS, 1, PPC::R0).addSImm(NegNumbytes >> 16);
    MBB.insert(MBBI, MI);
    MI = BuildMI(PPC::ORI, 2, PPC::R0).addReg(PPC::R0)
      .addImm(NegNumbytes & 0xFFFF);
    MBB.insert(MBBI, MI);
    MI = BuildMI(StoreOp, 3).addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0);
    MBB.insert(MBBI, MI);
  }

  if (hasFP(MF)) {
    unsigned StoreOp = is64bit ? PPC::STD : PPC::STW;
    MI = BuildMI(StoreOp, 3).addReg(PPC::R31).addSImm(R1Size).addReg(PPC::R1);
    MBB.insert(MBBI, MI);
    MI = BuildMI(PPC::OR, 2, PPC::R31).addReg(PPC::R1).addReg(PPC::R1);
    MBB.insert(MBBI, MI);
  }
}

void PowerPCRegisterInfo::emitEpilogue(MachineFunction &MF,
                                       MachineBasicBlock &MBB) const {
  const MachineFrameInfo *MFI = MF.getFrameInfo();
  MachineBasicBlock::iterator MBBI = prior(MBB.end());
  MachineInstr *MI;
  assert(MBBI->getOpcode() == PPC::BLR &&
         "Can only insert epilog into returning blocks");

  // Get the number of bytes allocated from the FrameInfo...
  unsigned NumBytes = MFI->getStackSize();

  if (NumBytes != 0) {
    unsigned Opcode = is64bit ? PPC::LD : PPC::LWZ;
    unsigned Offset = is64bit ? 8 : 4;
    if (hasFP(MF)) {
      MI = BuildMI(PPC::OR, 2, PPC::R1).addReg(PPC::R31).addReg(PPC::R31);
      MBB.insert(MBBI, MI);
      MI = BuildMI(Opcode, 2, PPC::R31).addSImm(Offset).addReg(PPC::R31);
      MBB.insert(MBBI, MI);
    }
    MI = BuildMI(Opcode, 2, PPC::R1).addSImm(0).addReg(PPC::R1);
    MBB.insert(MBBI, MI);
  }
}

#include "PowerPCGenRegisterInfo.inc"

const TargetRegisterClass*
PowerPCRegisterInfo::getRegClassForType(const Type* Ty) const {
  switch (Ty->getTypeID()) {
    default:              assert(0 && "Invalid type to getClass!");
    case Type::LongTyID:
    case Type::ULongTyID:
      if (!is64bit) assert(0 && "Long values can't fit in registers!");
    case Type::BoolTyID:
    case Type::SByteTyID:
    case Type::UByteTyID:
    case Type::ShortTyID:
    case Type::UShortTyID:
    case Type::IntTyID:
    case Type::UIntTyID:
    case Type::PointerTyID: return &GPRCInstance;

    case Type::FloatTyID:
    case Type::DoubleTyID: return &FPRCInstance;
  }
}

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qgeotiledmapdata.h"
#include "qgeotiledmapdata_p.h"

#include "qgeotiledmappingmanagerengine.h"
#include "qgeocoordinate.h"

#include <QDebug>

#define DEFAULT_ZOOMLEVEL 8
#define PI 3.14159265
#include <math.h>

QTM_BEGIN_NAMESPACE

QGeoTiledMapData::QGeoTiledMapData(QGeoMappingManagerEngine *engine, QGeoMapWidget *widget)
        : QGeoMapData(engine, widget),
        d_ptr(new QGeoTiledMapDataPrivate())
{
    QGeoTiledMappingManagerEngine *tileEngine = static_cast<QGeoTiledMappingManagerEngine *>(QGeoMapData::engine());
    QGeoMapData::setZoomLevel(DEFAULT_ZOOMLEVEL);
    d_ptr->width = (1 << DEFAULT_ZOOMLEVEL) * tileEngine->tileSize().width();
    d_ptr->height = (1 << DEFAULT_ZOOMLEVEL) * tileEngine->tileSize().height();
}

QGeoTiledMapData::~QGeoTiledMapData()
{
}

QPointF QGeoTiledMapData::coordinateToScreenPosition(const QGeoCoordinate &coordinate) const
{
    qulonglong worldX;
    qulonglong worldY;

    coordinateToWorldPixel(coordinate, &worldX, &worldY);
    QPointF pos(worldX, worldY);
    pos -= d_ptr->screenRect.topLeft();
    return pos;
}

QGeoCoordinate QGeoTiledMapData::screenPositionToCoordinate(const QPointF &screenPosition) const
{
    qulonglong worldX = static_cast<qulonglong>(d_ptr->screenRect.left() + screenPosition.x()) % d_ptr->width;
    qulonglong worldY = static_cast<qulonglong>(d_ptr->screenRect.top() + screenPosition.y()) % d_ptr->height;

    return worldPixelToCoordinate(worldX, worldY);
}

/*!
    Returns the (row,col) index of the tile that \a screenPosition lies on.
    The screen position (0,0) represents the top-left corner of the current map view.
*/
QPoint QGeoTiledMapData::screenPositionToTileIndices(const QPointF &screenPosition) const
{
    //TODO: add some type checking
    QGeoTiledMappingManagerEngine *tileEngine = static_cast<QGeoTiledMappingManagerEngine *>(QGeoMapData::engine());
    QPointF pos = d_ptr->screenRect.topLeft() + screenPosition;

    int tileX = pos.x() / tileEngine->tileSize().width();
    int tileY = pos.y() / tileEngine->tileSize().height();

    return QPoint(tileX, tileY);
}

void QGeoTiledMapData::coordinateToWorldPixel(const QGeoCoordinate &coordinate, qulonglong *x, qulonglong *y) const
{
    double lng = coordinate.longitude(); //x
    double lat = coordinate.latitude(); //y

    lng = lng / 360.0 + 0.5;

    lat = 0.5 - (log(tan((PI / 4.0) + (PI / 2.0) * lat / 180.0)) / PI) / 2.0;
    lat = qMax(0.0, lat);
    lat = qMin(1.0, lat);

    *x = qRound64(lng * qreal(d_ptr->width));
    *y = qRound64(lat * qreal(d_ptr->height));
}

qreal rmod(const qreal a, const qreal b)
{
    quint64 div = static_cast<quint64>(a / b);
    return a - static_cast<qreal>(div) * b;
}

QGeoCoordinate QGeoTiledMapData::worldPixelToCoordinate(qulonglong x, qulonglong y) const
{
    qreal fx = qreal(x) / qreal(d_ptr->width);
    qreal fy = qreal(y) / qreal(d_ptr->height);

    if (fy < 0.0f)
        fy = 0.0f;
    else if (fy > 1.0f)
        fy = 1.0f;

    qreal lat;

    if (fy == 0.0f)
        lat = 90.0f;
    else if (fy == 1.0f)
        lat = -90.0f;
    else
        lat = (180.0f / PI) * (2.0f * atan(exp(PI * (1.0f - 2.0f * fy))) - (PI / 2.0f));

    qreal lng;
    if (fx >= 0) {
        lng = rmod(fx, 1.0f);
    } else {
        lng = rmod(1.0f - rmod(-1.0f * fx, 1.0f), 1.0f);
    }

    lng = lng * 360.0f - 180.0f;

    return QGeoCoordinate(lat, lng);
}

void QGeoTiledMapData::setCenter(const QGeoCoordinate &center)
{
    d_ptr->protectRegion = QRectF();
    qulonglong x;
    qulonglong y;
    coordinateToWorldPixel(center, &x, &y);
    d_ptr->screenRect.moveCenter(QPointF(x, y));
}

QGeoCoordinate QGeoTiledMapData::center() const
{
    QPointF center = d_ptr->screenRect.center();
    return worldPixelToCoordinate(center.x(), center.y());
}

void QGeoTiledMapData::setZoomLevel(qreal zoomLevel)
{
    qreal oldZoomLevel = QGeoMapData::zoomLevel();

    QGeoMapData::setZoomLevel(zoomLevel);

    // QGeoMapData::setZoomLevel clips the zoom level to be
    // in between the minimum and maximum zoom levels
    zoomLevel = QGeoMapData::zoomLevel();

    int zoomDiff = qRound(zoomLevel - oldZoomLevel);

    if (zoomDiff == 0)
        return;

    d_ptr->protectRegion = QRectF();

    //compute new screenRect
    qreal ratioX = d_ptr->screenRect.center().x() / d_ptr->width;
    qreal ratioY = d_ptr->screenRect.center().y() / d_ptr->height;
    //TODO: add some type checking
    QGeoTiledMappingManagerEngine *tileEngine = static_cast<QGeoTiledMappingManagerEngine *>(QGeoMapData::engine());
    d_ptr->width = (1 << static_cast<int>(zoomLevel)) * tileEngine->tileSize().width();
    d_ptr->height = (1 << static_cast<int>(zoomLevel)) * tileEngine->tileSize().height();
    QPointF newCenter(qRound(ratioX * d_ptr->width), qRound(ratioY * d_ptr->height));
    d_ptr->screenRect.moveCenter(newCenter);

    //scale old image
    QRectF target = QGeoMapData::mapImage().rect();
    qreal width = target.width() / (1 << qAbs(zoomDiff));
    qreal height = target.width() / (1 << qAbs(zoomDiff));
    qreal x = target.x() + ((target.width() - width) / 2.0);
    qreal y = target.y() + ((target.height() - height) / 2.0);
    QRectF source = QRectF(x, y, width, height);

    QPixmap pm(QGeoMapData::mapImage().size());
    QPainter painter(&pm);

    if (zoomDiff < 0) {
        painter.drawPixmap(source, QGeoMapData::mapImage(), target);
    } else {
        painter.drawPixmap(target, QGeoMapData::mapImage(), source);
    }

    setMapImage(pm);
}

void QGeoTiledMapData::setViewportSize(const QSizeF &size)
{
    d_ptr->protectRegion = d_ptr->screenRect;
    d_ptr->screenRect.setSize(size);
    QGeoMapData::setViewportSize(size);

    QPixmap pm(size.toSize());
    QPainter p(&pm);
    if (!QGeoMapData::mapImage().isNull())
        p.drawPixmap(QGeoMapData::mapImage().rect(), QGeoMapData::mapImage(), QGeoMapData::mapImage().rect());
    setMapImage(pm);
}

void QGeoTiledMapData::pan(int dx, int dy)
{
    QRectF oldScreenRect(d_ptr->screenRect);
    d_ptr->screenRect.translate(dx, dy);

    //Have we crossed the dateline from east-->west (i.e. "left edge")
    while (d_ptr->screenRect.left() < 0) {
        d_ptr->screenRect.translate(d_ptr->width, 0);
    }

    //Have we crossed the dateline from west-->east (i.e. "right edge")
    if (d_ptr->screenRect.left()>= d_ptr->width) {
        d_ptr->screenRect.moveLeft(static_cast<qulonglong>(d_ptr->screenRect.left()) % d_ptr->width);
    }

    qreal deltaX = oldScreenRect.left() - d_ptr->screenRect.left();
    qreal deltaY = oldScreenRect.top() - d_ptr->screenRect.top();
    qreal sx;
    qreal sy;
    qreal tx;
    qreal ty;

    //TODO: make this work in case we wrapped around the date line
    if (deltaX >= 0) {
        sx = 0.0;
        tx = deltaX;
    } else {
        sx = qAbs(deltaX);
        tx = 0.0;
    }

    if (deltaY >= 0) {
        sy = 0.0;
        ty = deltaY;
    } else {
        sy = qAbs(deltaY);
        ty = 0.0;
    }

    QRectF source = QRectF(sx, sy, QGeoMapData::mapImage().width(), QGeoMapData::mapImage().height());
    QRectF target = QRectF(tx, ty, QGeoMapData::mapImage().width(), QGeoMapData::mapImage().height());

    QPixmap pm(QGeoMapData::mapImage().size());
    QPainter p(&pm);
    if (!QGeoMapData::mapImage().isNull()) {
        p.drawPixmap(target, QGeoMapData::mapImage(), source);
        //TODO: is this correct?
        d_ptr->protectRegion = target.translated(d_ptr->screenRect.topLeft());
        setMapImage(pm);
    }
}

QRectF QGeoTiledMapData::screenRect() const
{
    return d_ptr->screenRect;
}

QRectF QGeoTiledMapData::protectedRegion() const
{
    return d_ptr->protectRegion;
}

void QGeoTiledMapData::clearProtectedRegion()
{
    d_ptr->protectRegion = QRectF();
}

QList<QGeoMapObject*> QGeoTiledMapData::visibleMapObjects()
{
    return QList<QGeoMapObject*>();
}

QList<QGeoMapObject*> QGeoTiledMapData::mapObjectsAtScreenPosition(const QPointF &screenPosition, int radius)
{
    return QList<QGeoMapObject*>();
}

QList<QGeoMapObject*> QGeoTiledMapData::mapObjectsInScreenRect(const QRectF &screenRect)
{
    return QList<QGeoMapObject*>();
}

/*******************************************************************************
*******************************************************************************/

QGeoTiledMapDataPrivate::QGeoTiledMapDataPrivate() {}

QGeoTiledMapDataPrivate::QGeoTiledMapDataPrivate(const QGeoTiledMapDataPrivate &other)
        : width(other.width),
        height(other.height),
        protectRegion(other.protectRegion),
        screenRect(other.screenRect) {}

QGeoTiledMapDataPrivate::~QGeoTiledMapDataPrivate() {}

QGeoTiledMapDataPrivate& QGeoTiledMapDataPrivate::operator= (const QGeoTiledMapDataPrivate & other)
{
    width = other.width;
    height = other.height;
    protectRegion = other.protectRegion;
    screenRect = other.screenRect;

    return *this;
}

QTM_END_NAMESPACE
<commit_msg>Fixed scrambled line issue in map display<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qgeotiledmapdata.h"
#include "qgeotiledmapdata_p.h"

#include "qgeotiledmappingmanagerengine.h"
#include "qgeocoordinate.h"

#include <QDebug>

#define DEFAULT_ZOOMLEVEL 8
#define PI 3.14159265
#include <math.h>

QTM_BEGIN_NAMESPACE

QGeoTiledMapData::QGeoTiledMapData(QGeoMappingManagerEngine *engine, QGeoMapWidget *widget)
        : QGeoMapData(engine, widget),
        d_ptr(new QGeoTiledMapDataPrivate())
{
    QGeoTiledMappingManagerEngine *tileEngine = static_cast<QGeoTiledMappingManagerEngine *>(QGeoMapData::engine());
    QGeoMapData::setZoomLevel(DEFAULT_ZOOMLEVEL);
    d_ptr->width = (1 << DEFAULT_ZOOMLEVEL) * tileEngine->tileSize().width();
    d_ptr->height = (1 << DEFAULT_ZOOMLEVEL) * tileEngine->tileSize().height();
}

QGeoTiledMapData::~QGeoTiledMapData()
{
}

QPointF QGeoTiledMapData::coordinateToScreenPosition(const QGeoCoordinate &coordinate) const
{
    qulonglong worldX;
    qulonglong worldY;

    coordinateToWorldPixel(coordinate, &worldX, &worldY);
    QPointF pos(worldX, worldY);
    pos -= d_ptr->screenRect.topLeft();
    return pos;
}

QGeoCoordinate QGeoTiledMapData::screenPositionToCoordinate(const QPointF &screenPosition) const
{
    qulonglong worldX = static_cast<qulonglong>(d_ptr->screenRect.left() + screenPosition.x()) % d_ptr->width;
    qulonglong worldY = static_cast<qulonglong>(d_ptr->screenRect.top() + screenPosition.y()) % d_ptr->height;

    return worldPixelToCoordinate(worldX, worldY);
}

/*!
    Returns the (row,col) index of the tile that \a screenPosition lies on.
    The screen position (0,0) represents the top-left corner of the current map view.
*/
QPoint QGeoTiledMapData::screenPositionToTileIndices(const QPointF &screenPosition) const
{
    //TODO: add some type checking
    QGeoTiledMappingManagerEngine *tileEngine = static_cast<QGeoTiledMappingManagerEngine *>(QGeoMapData::engine());
    QPointF pos = d_ptr->screenRect.topLeft() + screenPosition;

    int tileX = pos.x() / tileEngine->tileSize().width();
    int tileY = pos.y() / tileEngine->tileSize().height();

    return QPoint(tileX, tileY);
}

void QGeoTiledMapData::coordinateToWorldPixel(const QGeoCoordinate &coordinate, qulonglong *x, qulonglong *y) const
{
    double lng = coordinate.longitude(); //x
    double lat = coordinate.latitude(); //y

    lng = lng / 360.0 + 0.5;

    lat = 0.5 - (log(tan((PI / 4.0) + (PI / 2.0) * lat / 180.0)) / PI) / 2.0;
    lat = qMax(0.0, lat);
    lat = qMin(1.0, lat);

    *x = qRound64(lng * qreal(d_ptr->width));
    *y = qRound64(lat * qreal(d_ptr->height));
}

qreal rmod(const qreal a, const qreal b)
{
    quint64 div = static_cast<quint64>(a / b);
    return a - static_cast<qreal>(div) * b;
}

QGeoCoordinate QGeoTiledMapData::worldPixelToCoordinate(qulonglong x, qulonglong y) const
{
    qreal fx = qreal(x) / qreal(d_ptr->width);
    qreal fy = qreal(y) / qreal(d_ptr->height);

    if (fy < 0.0f)
        fy = 0.0f;
    else if (fy > 1.0f)
        fy = 1.0f;

    qreal lat;

    if (fy == 0.0f)
        lat = 90.0f;
    else if (fy == 1.0f)
        lat = -90.0f;
    else
        lat = (180.0f / PI) * (2.0f * atan(exp(PI * (1.0f - 2.0f * fy))) - (PI / 2.0f));

    qreal lng;
    if (fx >= 0) {
        lng = rmod(fx, 1.0f);
    } else {
        lng = rmod(1.0f - rmod(-1.0f * fx, 1.0f), 1.0f);
    }

    lng = lng * 360.0f - 180.0f;

    return QGeoCoordinate(lat, lng);
}

void QGeoTiledMapData::setCenter(const QGeoCoordinate &center)
{
    d_ptr->protectRegion = QRectF();
    qulonglong x;
    qulonglong y;
    coordinateToWorldPixel(center, &x, &y);
    d_ptr->screenRect.moveCenter(QPointF(x, y));
    d_ptr->screenRect.moveLeft(qRound64(d_ptr->screenRect.left()));
    d_ptr->screenRect.moveTop(qRound64(d_ptr->screenRect.top()));
}

QGeoCoordinate QGeoTiledMapData::center() const
{
    QPointF center = d_ptr->screenRect.center();
    return worldPixelToCoordinate(center.x(), center.y());
}

void QGeoTiledMapData::setZoomLevel(qreal zoomLevel)
{
    qreal oldZoomLevel = QGeoMapData::zoomLevel();

    QGeoMapData::setZoomLevel(zoomLevel);

    // QGeoMapData::setZoomLevel clips the zoom level to be
    // in between the minimum and maximum zoom levels
    zoomLevel = QGeoMapData::zoomLevel();

    int zoomDiff = qRound(zoomLevel - oldZoomLevel);

    if (zoomDiff == 0)
        return;

    d_ptr->protectRegion = QRectF();

    //compute new screenRect
    qreal ratioX = d_ptr->screenRect.center().x() / d_ptr->width;
    qreal ratioY = d_ptr->screenRect.center().y() / d_ptr->height;
    //TODO: add some type checking
    QGeoTiledMappingManagerEngine *tileEngine = static_cast<QGeoTiledMappingManagerEngine *>(QGeoMapData::engine());
    d_ptr->width = (1 << static_cast<int>(zoomLevel)) * tileEngine->tileSize().width();
    d_ptr->height = (1 << static_cast<int>(zoomLevel)) * tileEngine->tileSize().height();
    QPointF newCenter(qRound(ratioX * d_ptr->width), qRound(ratioY * d_ptr->height));
    d_ptr->screenRect.moveCenter(newCenter);

    //scale old image
    QRectF target = QGeoMapData::mapImage().rect();
    qreal width = target.width() / (1 << qAbs(zoomDiff));
    qreal height = target.width() / (1 << qAbs(zoomDiff));
    qreal x = target.x() + ((target.width() - width) / 2.0);
    qreal y = target.y() + ((target.height() - height) / 2.0);
    QRectF source = QRectF(x, y, width, height);

    QPixmap pm(QGeoMapData::mapImage().size());
    QPainter painter(&pm);

    if (zoomDiff < 0) {
        painter.drawPixmap(source, QGeoMapData::mapImage(), target);
    } else {
        painter.drawPixmap(target, QGeoMapData::mapImage(), source);
    }

    setMapImage(pm);
}

void QGeoTiledMapData::setViewportSize(const QSizeF &size)
{
    d_ptr->protectRegion = d_ptr->screenRect;
    d_ptr->screenRect.setSize(size);
    QGeoMapData::setViewportSize(size);

    QPixmap pm(size.toSize());
    QPainter p(&pm);
    if (!QGeoMapData::mapImage().isNull())
        p.drawPixmap(QGeoMapData::mapImage().rect(), QGeoMapData::mapImage(), QGeoMapData::mapImage().rect());
    setMapImage(pm);
}

void QGeoTiledMapData::pan(int dx, int dy)
{
    QRectF oldScreenRect(d_ptr->screenRect);
    d_ptr->screenRect.translate(dx, dy);

    //Have we crossed the dateline from east-->west (i.e. "left edge")
    while (d_ptr->screenRect.left() < 0) {
        d_ptr->screenRect.translate(d_ptr->width, 0);
    }

    //Have we crossed the dateline from west-->east (i.e. "right edge")
    if (d_ptr->screenRect.left()>= d_ptr->width) {
        d_ptr->screenRect.moveLeft(static_cast<qulonglong>(d_ptr->screenRect.left()) % d_ptr->width);
    }

    qreal deltaX = oldScreenRect.left() - d_ptr->screenRect.left();
    qreal deltaY = oldScreenRect.top() - d_ptr->screenRect.top();
    qreal sx;
    qreal sy;
    qreal tx;
    qreal ty;

    //TODO: make this work in case we wrapped around the date line
    if (deltaX >= 0) {
        sx = 0.0;
        tx = deltaX;
    } else {
        sx = qAbs(deltaX);
        tx = 0.0;
    }

    if (deltaY >= 0) {
        sy = 0.0;
        ty = deltaY;
    } else {
        sy = qAbs(deltaY);
        ty = 0.0;
    }

    QRectF source = QRectF(sx, sy, QGeoMapData::mapImage().width(), QGeoMapData::mapImage().height());
    QRectF target = QRectF(tx, ty, QGeoMapData::mapImage().width(), QGeoMapData::mapImage().height());

    QPixmap pm(QGeoMapData::mapImage().size());
    QPainter p(&pm);
    if (!QGeoMapData::mapImage().isNull()) {
        p.drawPixmap(target, QGeoMapData::mapImage(), source);
        //TODO: is this correct?
        d_ptr->protectRegion = target.translated(d_ptr->screenRect.topLeft());
        setMapImage(pm);
    }
}

QRectF QGeoTiledMapData::screenRect() const
{
    return d_ptr->screenRect;
}

QRectF QGeoTiledMapData::protectedRegion() const
{
    return d_ptr->protectRegion;
}

void QGeoTiledMapData::clearProtectedRegion()
{
    d_ptr->protectRegion = QRectF();
}

QList<QGeoMapObject*> QGeoTiledMapData::visibleMapObjects()
{
    return QList<QGeoMapObject*>();
}

QList<QGeoMapObject*> QGeoTiledMapData::mapObjectsAtScreenPosition(const QPointF &screenPosition, int radius)
{
    return QList<QGeoMapObject*>();
}

QList<QGeoMapObject*> QGeoTiledMapData::mapObjectsInScreenRect(const QRectF &screenRect)
{
    return QList<QGeoMapObject*>();
}

/*******************************************************************************
*******************************************************************************/

QGeoTiledMapDataPrivate::QGeoTiledMapDataPrivate() {}

QGeoTiledMapDataPrivate::QGeoTiledMapDataPrivate(const QGeoTiledMapDataPrivate &other)
        : width(other.width),
        height(other.height),
        protectRegion(other.protectRegion),
        screenRect(other.screenRect) {}

QGeoTiledMapDataPrivate::~QGeoTiledMapDataPrivate() {}

QGeoTiledMapDataPrivate& QGeoTiledMapDataPrivate::operator= (const QGeoTiledMapDataPrivate & other)
{
    width = other.width;
    height = other.height;
    protectRegion = other.protectRegion;
    screenRect = other.screenRect;

    return *this;
}

QTM_END_NAMESPACE
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "stdafx.h"
#include "Spinneret.h"
#include "WebView.h"
#include "WebFrame.h"

#include <commctrl.h>

#define MAX_LOADSTRING 100
#define URLBAR_HEIGHT  24

using namespace WebKit;

// Global Variables:
HINSTANCE hInst;                                // current instance
HWND hMainWnd;
HWND hURLBarWnd;
long DefEditProc;
WebView* gWebView = 0;
WebHost* gWebHost = 0;
TCHAR szTitle[MAX_LOADSTRING];                    // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name

// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK    MyEditProc(HWND, UINT, WPARAM, LPARAM);

void SpinneretWebHost::updateLocationBar(const char* URL)
{
    SendMessageA(hURLBarWnd, (UINT)WM_SETTEXT, 0, (LPARAM)URL);
}

void SpinneretWebHost::loadEnd(BOOL successful, DWORD error, LPCTSTR errorString)
{
}

static void resizeSubViews()
{
    RECT rcClient;
    GetClientRect(hMainWnd, &rcClient);
    MoveWindow(hURLBarWnd, 0, 0, rcClient.right, URLBAR_HEIGHT, TRUE);
    MoveWindow(gWebView->windowHandle(), 0, URLBAR_HEIGHT, rcClient.right, rcClient.bottom - URLBAR_HEIGHT, TRUE);
}

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
#ifdef _CRTDBG_MAP_ALLOC
    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
#endif

    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

     // TODO: Place code here.
    MSG msg;
    HACCEL hAccelTable;

    INITCOMMONCONTROLSEX InitCtrlEx;

    InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
    InitCtrlEx.dwICC  = ICC_STANDARD_CLASSES;
    InitCommonControlsEx(&InitCtrlEx);

    // Initialize global strings
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadString(hInstance, IDC_SPINNERET, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow))
        return FALSE;

    hURLBarWnd = CreateWindow(L"EDIT", 0,
                        WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL,
                        0, 0, 0, 0,
                        hMainWnd,
                        0,
                        hInstance, 0);

    DefEditProc = GetWindowLong(hURLBarWnd, GWL_WNDPROC);
    SetWindowLong(hURLBarWnd, GWL_WNDPROC,(long)MyEditProc);
    SetFocus(hURLBarWnd);

    gWebHost = new SpinneretWebHost();
    gWebView = WebView::createWebView(hInstance, hMainWnd, gWebHost);
    gWebView->mainFrame()->loadHTMLString("
Testing

div with blue border

foo
bar
baz
");

    resizeSubViews();
    ShowWindow(gWebView->windowHandle(), nCmdShow);
    UpdateWindow(gWebView->windowHandle());

    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SPINNERET));

    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    delete gWebView;
#ifdef _CRTDBG_MAP_ALLOC
    _CrtDumpMemoryLeaks();
#endif

    return (int) msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = 0;
    wcex.hInstance        = hInstance;
    wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SPINNERET));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = 0;
    wcex.lpszMenuName    = MAKEINTRESOURCE(IDC_SPINNERET);
    wcex.lpszClassName    = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // Store instance handle in our global variable

   hMainWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hMainWnd)
      return FALSE;

   ShowWindow(hMainWnd, nCmdShow);
   UpdateWindow(hMainWnd);

   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_SIZE:
        if (!gWebView)
            break;
        resizeSubViews();
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

#define MAX_URL_LENGTH  1024

LRESULT CALLBACK MyEditProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message) {
        case WM_CHAR:
            if( wParam == 13 ) { // Enter Key
                wchar_t strPtr[MAX_URL_LENGTH];
                char    cstrPtr[MAX_URL_LENGTH];
                *((LPWORD)strPtr) = MAX_URL_LENGTH;
                int strLen = SendMessage(hDlg, EM_GETLINE, 0, (LPARAM)strPtr);

                int x;
                for(x = 0; x < strLen; x++)
                    cstrPtr[x] = strPtr[x];
                cstrPtr[x] = 0;

                gWebView->mainFrame()->loadURL(cstrPtr);
                SetFocus(gWebView->windowHandle());

                return 0;
            } else
                return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam);
            break;
        default:
             return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam);
        break;
    }
    return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}
<commit_msg>Make sure Spinneret inits and shuts down COM like a good boy.<commit_after>/*
 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "stdafx.h"
#include "Spinneret.h"
#include "WebView.h"
#include "WebFrame.h"

#include <commctrl.h>
#include <objbase.h>

#define MAX_LOADSTRING 100
#define URLBAR_HEIGHT  24

using namespace WebKit;

// Global Variables:
HINSTANCE hInst;                                // current instance
HWND hMainWnd;
HWND hURLBarWnd;
long DefEditProc;
WebView* gWebView = 0;
WebHost* gWebHost = 0;
TCHAR szTitle[MAX_LOADSTRING];                    // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name

// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK    MyEditProc(HWND, UINT, WPARAM, LPARAM);

void SpinneretWebHost::updateLocationBar(const char* URL)
{
    SendMessageA(hURLBarWnd, (UINT)WM_SETTEXT, 0, (LPARAM)URL);
}

void SpinneretWebHost::loadEnd(BOOL successful, DWORD error, LPCTSTR errorString)
{
}

static void resizeSubViews()
{
    RECT rcClient;
    GetClientRect(hMainWnd, &rcClient);
    MoveWindow(hURLBarWnd, 0, 0, rcClient.right, URLBAR_HEIGHT, TRUE);
    MoveWindow(gWebView->windowHandle(), 0, URLBAR_HEIGHT, rcClient.right, rcClient.bottom - URLBAR_HEIGHT, TRUE);
}

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
#ifdef _CRTDBG_MAP_ALLOC
    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
#endif

    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

     // TODO: Place code here.
    MSG msg;
    HACCEL hAccelTable;

    INITCOMMONCONTROLSEX InitCtrlEx;

    InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
    InitCtrlEx.dwICC  = ICC_STANDARD_CLASSES;
    InitCommonControlsEx(&InitCtrlEx);

    // Initialize global strings
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadString(hInstance, IDC_SPINNERET, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow))
        return FALSE;

    // Init COM
    CoInitialize(NULL);

    hURLBarWnd = CreateWindow(L"EDIT", 0,
                        WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL,
                        0, 0, 0, 0,
                        hMainWnd,
                        0,
                        hInstance, 0);

    DefEditProc = GetWindowLong(hURLBarWnd, GWL_WNDPROC);
    SetWindowLong(hURLBarWnd, GWL_WNDPROC,(long)MyEditProc);
    SetFocus(hURLBarWnd);

    gWebHost = new SpinneretWebHost();
    gWebView = WebView::createWebView(hInstance, hMainWnd, gWebHost);
    gWebView->mainFrame()->loadHTMLString("
Testing

div with blue border

foo
bar
baz
");

    resizeSubViews();
    ShowWindow(gWebView->windowHandle(), nCmdShow);
    UpdateWindow(gWebView->windowHandle());

    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SPINNERET));

    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    delete gWebView;
#ifdef _CRTDBG_MAP_ALLOC
    _CrtDumpMemoryLeaks();
#endif

    // Shut down COM.
    CoUninitialize();

    return (int) msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = 0;
    wcex.hInstance        = hInstance;
    wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SPINNERET));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = 0;
    wcex.lpszMenuName    = MAKEINTRESOURCE(IDC_SPINNERET);
    wcex.lpszClassName    = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // Store instance handle in our global variable

   hMainWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hMainWnd)
      return FALSE;

   ShowWindow(hMainWnd, nCmdShow);
   UpdateWindow(hMainWnd);

   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_SIZE:
        if (!gWebView)
            break;
        resizeSubViews();
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

#define MAX_URL_LENGTH  1024

LRESULT CALLBACK MyEditProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message) {
        case WM_CHAR:
            if( wParam == 13 ) { // Enter Key
                wchar_t strPtr[MAX_URL_LENGTH];
                char    cstrPtr[MAX_URL_LENGTH];
                *((LPWORD)strPtr) = MAX_URL_LENGTH;
                int strLen = SendMessage(hDlg, EM_GETLINE, 0, (LPARAM)strPtr);

                int x;
                for(x = 0; x < strLen; x++)
                    cstrPtr[x] = strPtr[x];
                cstrPtr[x] = 0;

                gWebView->mainFrame()->loadURL(cstrPtr);
                SetFocus(gWebView->windowHandle());

                return 0;
            } else
                return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam);
            break;
        default:
             return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam);
        break;
    }
    return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/dreamview/backend/common/dreamview_gflags.h"

DEFINE_string(dreamview_module_name, "dreamview", "dreamview module name");

DEFINE_bool(dreamview_profiling_mode, false, "Run dreamview in profiling mode");

DEFINE_double(
    dreamview_profiling_duration, -1.0,
    "Dreamview profiling duration. Negative value will not restrict the "
    "profiling time");

DEFINE_string(dreamview_adapter_config_filename,
              "modules/dreamview/conf/adapter.conf", "The adapter config file");

DEFINE_string(hmi_config_filename, "modules/dreamview/conf/hmi.conf",
              "The HMI config file");

DEFINE_string(static_file_dir, "modules/dreamview/frontend/dist",
              "The path to the dreamview distribution directory. The default "
              "value points to built-in version from the Apollo project.");

DEFINE_string(server_ports, "8888",
              "Comma-separated list of ports to listen on. If the port is SSL, "
              "a letter s must be appended, for example, 80,443s will open "
              "port 80 and port 443.");

DEFINE_bool(routing_from_file, false,
            "Whether Dreamview reads initial routing response from file.");

DEFINE_string(routing_response_file,
              "modules/map/data/demo/garage_routing.pb.txt",
              "File path of the routing response that SimControl will read the "
              "start point from. If this is absent, SimControl will directly "
              "take the RoutingResponse from ROS to determine the start "
              "point.");

DEFINE_string(websocket_timeout_ms, "36000000",
              "Time span that CivetServer keeps the websocket connection alive "
              "without dropping it.");

DEFINE_string(ssl_certificate, "",
              "Path to the SSL certificate file. This option is only required "
              "when at least one of the listening_ports is SSL. The file must "
              "be in PEM format, and it must have both, private key and "
              "certificate");

DEFINE_double(sim_map_radius, 200.0,
              "The radius within which Dreamview will find all the map "
              "elements around the car.");

DEFINE_int32(dreamview_worker_num, 3, "number of dreamview thread workers");

DEFINE_bool(enable_update_size_check, true,
            "True to check if the update byte number is less than threshold");

DEFINE_uint32(max_update_size, 1000000,
              "Number of max update bytes allowed to push to dreamview FE");

DEFINE_bool(sim_world_with_routing_path, false,
            "Whether the routing_path is included in sim_world proto.");
<commit_msg>dreamview: use one thread to avoid multi-thread issues<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/dreamview/backend/common/dreamview_gflags.h"

DEFINE_string(dreamview_module_name, "dreamview", "dreamview module name");

DEFINE_bool(dreamview_profiling_mode, false, "Run dreamview in profiling mode");

DEFINE_double(
    dreamview_profiling_duration, -1.0,
    "Dreamview profiling duration. Negative value will not restrict the "
    "profiling time");

DEFINE_string(dreamview_adapter_config_filename,
              "modules/dreamview/conf/adapter.conf", "The adapter config file");

DEFINE_string(hmi_config_filename, "modules/dreamview/conf/hmi.conf",
              "The HMI config file");

DEFINE_string(static_file_dir, "modules/dreamview/frontend/dist",
              "The path to the dreamview distribution directory. The default "
              "value points to built-in version from the Apollo project.");

DEFINE_string(server_ports, "8888",
              "Comma-separated list of ports to listen on. If the port is SSL, "
              "a letter s must be appended, for example, 80,443s will open "
              "port 80 and port 443.");

DEFINE_bool(routing_from_file, false,
            "Whether Dreamview reads initial routing response from file.");

DEFINE_string(routing_response_file,
              "modules/map/data/demo/garage_routing.pb.txt",
              "File path of the routing response that SimControl will read the "
              "start point from. If this is absent, SimControl will directly "
              "take the RoutingResponse from ROS to determine the start "
              "point.");

DEFINE_string(websocket_timeout_ms, "36000000",
              "Time span that CivetServer keeps the websocket connection alive "
              "without dropping it.");

DEFINE_string(ssl_certificate, "",
              "Path to the SSL certificate file. This option is only required "
              "when at least one of the listening_ports is SSL. The file must "
              "be in PEM format, and it must have both, private key and "
              "certificate");

DEFINE_double(sim_map_radius, 200.0,
              "The radius within which Dreamview will find all the map "
              "elements around the car.");

DEFINE_int32(dreamview_worker_num, 1, "number of dreamview thread workers");

DEFINE_bool(enable_update_size_check, true,
            "True to check if the update byte number is less than threshold");

DEFINE_uint32(max_update_size, 1000000,
              "Number of max update bytes allowed to push to dreamview FE");

DEFINE_bool(sim_world_with_routing_path, false,
            "Whether the routing_path is included in sim_world proto.");
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <chrono>

#include "otbStopwatch.h"

namespace otb
{

Stopwatch
::Stopwatch()
    : m_ElapsedMilliseconds(), m_IsRunning()
{
}

void
Stopwatch
::Start()
{
  if (!this->m_IsRunning)
    {
    this->m_IsRunning = true;
    this->m_StartTime = this->GetTimestamp();
    }
}

void
Stopwatch
::Stop()
{
  if (this->m_IsRunning)
    {
    this->m_ElapsedMilliseconds += GetRunningElapsedTime();
    this->m_IsRunning = false;
    }
}

void
Stopwatch
::Reset()
{
  this->m_ElapsedMilliseconds = 0;
  this->m_IsRunning = false;
}

void
Stopwatch
::Restart()
{
  this->m_ElapsedMilliseconds = 0;
  this->m_IsRunning = true;
  this->m_StartTime = this->GetTimestamp();
}

Stopwatch::DurationType
Stopwatch
::GetElapsedMilliseconds() const
{
  auto result = this->m_ElapsedMilliseconds;

  if (this->m_IsRunning)
    result += this->GetRunningElapsedTime();

  return result;
}

bool
Stopwatch
::IsRunning() const
{
  return this->m_IsRunning;
}

Stopwatch
Stopwatch
::StartNew()
{
  Stopwatch sw;
  sw.Start();

  return sw;
}

inline
Stopwatch::TimepointType
Stopwatch
::GetTimestamp() const
{
  auto now = std::chrono::steady_clock::now();
  return std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
}

inline
Stopwatch::DurationType
Stopwatch
::GetRunningElapsedTime() const
{
  return this->GetTimestamp() - this->m_StartTime;
}

}
<commit_msg>COVERITY: non-static class member m_StartTime is not initialized in this constructor<commit_after>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <chrono>

#include "otbStopwatch.h"

namespace otb
{

Stopwatch
::Stopwatch()
  : m_StartTime(), m_ElapsedMilliseconds(), m_IsRunning()
{
}

void
Stopwatch
::Start()
{
  if (!this->m_IsRunning)
    {
    this->m_IsRunning = true;
    this->m_StartTime = this->GetTimestamp();
    }
}

void
Stopwatch
::Stop()
{
  if (this->m_IsRunning)
    {
    this->m_ElapsedMilliseconds += GetRunningElapsedTime();
    this->m_IsRunning = false;
    }
}

void
Stopwatch
::Reset()
{
  this->m_ElapsedMilliseconds = 0;
  this->m_IsRunning = false;
}

void
Stopwatch
::Restart()
{
  this->m_ElapsedMilliseconds = 0;
  this->m_IsRunning = true;
  this->m_StartTime = this->GetTimestamp();
}

Stopwatch::DurationType
Stopwatch
::GetElapsedMilliseconds() const
{
  auto result = this->m_ElapsedMilliseconds;

  if (this->m_IsRunning)
    result += this->GetRunningElapsedTime();

  return result;
}

bool
Stopwatch
::IsRunning() const
{
  return this->m_IsRunning;
}

Stopwatch
Stopwatch
::StartNew()
{
  Stopwatch sw;
  sw.Start();

  return sw;
}

inline
Stopwatch::TimepointType
Stopwatch
::GetTimestamp() const
{
  auto now = std::chrono::steady_clock::now();
  return std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
}

inline
Stopwatch::DurationType
Stopwatch
::GetRunningElapsedTime() const
{
  return this->GetTimestamp() - this->m_StartTime;
}

}
<|endoftext|>


<commit_before>#include "Pipeline.h"
#include "Voxel.h"
#include "Biome/BiomeStage.h"

namespace generator {

static Segment toSegment(Area area) {
    return Segment {area.x, area.y, area.worldWidth(), area.worldHeight(), 1.f, 0};
}

TiledMatrix* Pipeline::Data::get(StreamId stream) {
    if(stream.id >= count) return nullptr;
    if(matrices[stream.id].isEmpty()) return nullptr;
    return matrices + stream.id;
}

TiledMatrix* Pipeline::Data::getOrCreate(StreamId stream, Size detail) {
    if(stream.id >= count) resize(stream.id + 1);
    if(matrices[stream.id].isEmpty()) matrices[stream.id].create(detail, stream.itemBits, tileSize);
    return matrices + stream.id;
}

void Pipeline::Data::resize(Size count) {
    matrices = (TiledMatrix*)realloc(matrices, sizeof(TiledMatrix) * count);
    for(Size i = this->count; i < count; i++) {
        new (matrices + i) IdMatrix;
    }
    this->count = (U32)count;
}

void Pipeline::fillChunk(Chunk& chunk) {
    // Generate base data around the chunk location.
    auto segment = toSegment(chunk.area);
    landmassStage.generate(segment, *this);
    heightStage.generate(segment, *this);
    biomeStage.generate(segment, *this);

    // Generate the terrain for this chunk.
    if(auto biomes = data.get(Biomes)) {
        biomes->get(chunk.area.x, chunk.area.y, 0)
    }
}

} // namespace generator<commit_msg>Implemented simple biome generation<commit_after>#include "Pipeline.h"
#include "Voxel.h"
#include "Biome/BiomeStage.h"

namespace generator {

static Segment toSegment(Area area) {
    return Segment {area.x, area.y, (U32)area.worldWidth(), (U32)area.worldHeight(), 1.f, 0};
}

TiledMatrix* Pipeline::Data::get(StreamId stream) {
    if(stream.id >= count) return nullptr;
    if(matrices[stream.id].isEmpty()) return nullptr;
    return matrices + stream.id;
}

TiledMatrix* Pipeline::Data::getOrCreate(StreamId stream, Size detail) {
    if(stream.id >= count) resize(stream.id + 1);
    if(matrices[stream.id].isEmpty()) matrices[stream.id].create(detail, stream.itemBits, tileSize);
    return matrices + stream.id;
}

void Pipeline::Data::resize(Size count) {
    matrices = (TiledMatrix*)realloc(matrices, sizeof(TiledMatrix) * count);
    for(Size i = this->count; i < count; i++) {
        new (matrices + i) IdMatrix;
    }
    this->count = (U32)count;
}

void Pipeline::fillChunk(Chunk& chunk) {
    // Create a segment larger than the chunk size, which allows biomes to loop up metadata outside of the chunk area.
    auto segment = toSegment(chunk.area);
    segment.x -= chunk.area.width;
    segment.y -= chunk.area.height;
    segment.width += chunk.area.width * 2;
    segment.height += chunk.area.height * 2;

    // Generate base data around the chunk location.
    landmassStage.generate(segment, *this);
    heightStage.generate(segment, *this);
    biomeStage.generate(segment, *this);

    // Generate the terrain for this chunk.
    if(auto biomes = data.get(Biomes)) {
        auto id = (BiomeId)biomes->get(chunk.area.x, chunk.area.y, 0);
        auto biome = findBiome(id);
        biome(chunk, *this);
    }
}

} // namespace generator<|endoftext|>