-
Notifications
You must be signed in to change notification settings - Fork 1
/
vecgen-avx.hpp
77 lines (64 loc) · 2.47 KB
/
vecgen-avx.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Copyright 2013, Andrew Ross
// Distributable under the GNU LGPL v2.1 , see COPYING for details
#ifndef _VECGEN_AVX_HPP
#define _VECGEN_AVX_HPP
#include <map>
#include <list>
#include "avxgen.hpp"
// AVX-specific code generation. Used by vecgen after the
// architecture-independent stages. Uses an avxgen to generate the
// actual instructions.
//
// FIXME: the register allocator is pretty much entirely
// platform-neutral beyond an NREGS value. Move somewhere else?
class vecgen_avx {
public:
vecgen_avx(vecgen *vg) : vg(vg) {}
void codegen();
private:
enum mop { OP, SPILL, FILL, POOLTEST };
// AVX code generation keeps an augmented instruction record with
// physical registers, spill/fill marks, and pointers between loop
// endpoints.
struct avxinsn {
avxinsn(mop o) : mo(o), pdst(-1), pa(-1), pb(-1), pc(-1) { insn i={}; vi=i; }
avxinsn(insn i) : vi(i), mo(OP), pdst(-1), pa(-1), pb(-1), pc(-1) {}
insn vi;
mop mo;
int pdst, pa, pb, pc;
std::map<int,int> sphill; // spill/fill virt->phys registers
int addr; // generated code address
std::list<avxinsn>::iterator loop_match;
// Shorthand for SPILL/FILL, which reference just one reg
int sphill_v() { return sphill.begin()->first; }
int sphill_p() { return sphill.begin()->second; }
};
typedef std::list<avxinsn>::iterator aiptr;
struct regs { int r[16]; };
void dump();
void dump_insn(avxinsn& i);
void copy_code();
void fixup_bools();
void register_assignment();
void loop_reset(aiptr i, regs curr, regs &old);
void assign_scratch_slots();
avxgen::RegMem locate_reg(avxinsn &i, int r, bool &simd);
bool is_mutable(int r);
int fill_reg(int vr, aiptr ip, regs& regs);
int find_reg(int vr, aiptr ip, regs& regs);
void prune_regs(aiptr ip, regs& regs, std::list<int> *rorder=0);
void fill(aiptr ip, int vr, int r);
void spill(aiptr ip, int vr, int r);
void emit_load_store(avxgen& v, avxinsn& i);
void emit_cull(avxgen& v, aiptr i);
void emit_call(avxgen &v, int mi_cb, int mi_data);
std::vector<int> cull_regs(struct insn &i);
bool unassigned(aiptr ip, int r);
bool unused(aiptr ip, int r);
class vecgen *vg;
std::list<avxinsn> code;
std::map<int,int> scratch; // vr -> scratch slot
int bool_true; // immediate register id for 0x80000000
int nscratch; // max number of scratch registers on the stack
};
#endif // _VECGEN_AVX_HPP