Skip to content

Commit 3bd7efa

Browse files
committed
rustc_target: move in type definitions from rustc_trans::abi.
1 parent bdcd082 commit 3bd7efa

File tree

10 files changed

+242
-212
lines changed

10 files changed

+242
-212
lines changed

src/Cargo.lock

+1-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/librustc_target/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ path = "lib.rs"
99
crate-type = ["dylib"]
1010

1111
[dependencies]
12+
bitflags = "1.0"
13+
log = "0.4"
1214
syntax = { path = "../libsyntax" }
1315
serialize = { path = "../libserialize" }
14-
log = "0.4"
15-
rand = "0.4"
1616

1717
[features]
1818
jemalloc = []

src/librustc_target/abi/call.rs

+214
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use abi::{Align, HasDataLayout, Size};
12+
13+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
14+
pub enum PassMode {
15+
/// Ignore the argument (useful for empty struct).
16+
Ignore,
17+
/// Pass the argument directly.
18+
Direct(ArgAttributes),
19+
/// Pass a pair's elements directly in two arguments.
20+
Pair(ArgAttributes, ArgAttributes),
21+
/// Pass the argument after casting it, to either
22+
/// a single uniform or a pair of registers.
23+
Cast(CastTarget),
24+
/// Pass the argument indirectly via a hidden pointer.
25+
Indirect(ArgAttributes),
26+
}
27+
28+
// Hack to disable non_upper_case_globals only for the bitflags! and not for the rest
29+
// of this module
30+
pub use self::attr_impl::ArgAttribute;
31+
32+
#[allow(non_upper_case_globals)]
33+
#[allow(unused)]
34+
mod attr_impl {
35+
// The subset of llvm::Attribute needed for arguments, packed into a bitfield.
36+
bitflags! {
37+
#[derive(Default)]
38+
pub struct ArgAttribute: u16 {
39+
const ByVal = 1 << 0;
40+
const NoAlias = 1 << 1;
41+
const NoCapture = 1 << 2;
42+
const NonNull = 1 << 3;
43+
const ReadOnly = 1 << 4;
44+
const SExt = 1 << 5;
45+
const StructRet = 1 << 6;
46+
const ZExt = 1 << 7;
47+
const InReg = 1 << 8;
48+
}
49+
}
50+
}
51+
52+
/// A compact representation of LLVM attributes (at least those relevant for this module)
53+
/// that can be manipulated without interacting with LLVM's Attribute machinery.
54+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
55+
pub struct ArgAttributes {
56+
pub regular: ArgAttribute,
57+
pub pointee_size: Size,
58+
pub pointee_align: Option<Align>
59+
}
60+
61+
impl ArgAttributes {
62+
pub fn new() -> Self {
63+
ArgAttributes {
64+
regular: ArgAttribute::default(),
65+
pointee_size: Size::from_bytes(0),
66+
pointee_align: None,
67+
}
68+
}
69+
70+
pub fn set(&mut self, attr: ArgAttribute) -> &mut Self {
71+
self.regular = self.regular | attr;
72+
self
73+
}
74+
75+
pub fn contains(&self, attr: ArgAttribute) -> bool {
76+
self.regular.contains(attr)
77+
}
78+
}
79+
80+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
81+
pub enum RegKind {
82+
Integer,
83+
Float,
84+
Vector
85+
}
86+
87+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
88+
pub struct Reg {
89+
pub kind: RegKind,
90+
pub size: Size,
91+
}
92+
93+
macro_rules! reg_ctor {
94+
($name:ident, $kind:ident, $bits:expr) => {
95+
pub fn $name() -> Reg {
96+
Reg {
97+
kind: RegKind::$kind,
98+
size: Size::from_bits($bits)
99+
}
100+
}
101+
}
102+
}
103+
104+
impl Reg {
105+
reg_ctor!(i8, Integer, 8);
106+
reg_ctor!(i16, Integer, 16);
107+
reg_ctor!(i32, Integer, 32);
108+
reg_ctor!(i64, Integer, 64);
109+
110+
reg_ctor!(f32, Float, 32);
111+
reg_ctor!(f64, Float, 64);
112+
}
113+
114+
impl Reg {
115+
pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
116+
let dl = cx.data_layout();
117+
match self.kind {
118+
RegKind::Integer => {
119+
match self.size.bits() {
120+
1 => dl.i1_align,
121+
2...8 => dl.i8_align,
122+
9...16 => dl.i16_align,
123+
17...32 => dl.i32_align,
124+
33...64 => dl.i64_align,
125+
65...128 => dl.i128_align,
126+
_ => panic!("unsupported integer: {:?}", self)
127+
}
128+
}
129+
RegKind::Float => {
130+
match self.size.bits() {
131+
32 => dl.f32_align,
132+
64 => dl.f64_align,
133+
_ => panic!("unsupported float: {:?}", self)
134+
}
135+
}
136+
RegKind::Vector => dl.vector_align(self.size)
137+
}
138+
}
139+
}
140+
141+
/// An argument passed entirely registers with the
142+
/// same kind (e.g. HFA / HVA on PPC64 and AArch64).
143+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
144+
pub struct Uniform {
145+
pub unit: Reg,
146+
147+
/// The total size of the argument, which can be:
148+
/// * equal to `unit.size` (one scalar/vector)
149+
/// * a multiple of `unit.size` (an array of scalar/vectors)
150+
/// * if `unit.kind` is `Integer`, the last element
151+
/// can be shorter, i.e. `{ i64, i64, i32 }` for
152+
/// 64-bit integers with a total size of 20 bytes
153+
pub total: Size,
154+
}
155+
156+
impl From<Reg> for Uniform {
157+
fn from(unit: Reg) -> Uniform {
158+
Uniform {
159+
unit,
160+
total: unit.size
161+
}
162+
}
163+
}
164+
165+
impl Uniform {
166+
pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
167+
self.unit.align(cx)
168+
}
169+
}
170+
171+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
172+
pub struct CastTarget {
173+
pub prefix: [Option<RegKind>; 8],
174+
pub prefix_chunk: Size,
175+
pub rest: Uniform,
176+
}
177+
178+
impl From<Reg> for CastTarget {
179+
fn from(unit: Reg) -> CastTarget {
180+
CastTarget::from(Uniform::from(unit))
181+
}
182+
}
183+
184+
impl From<Uniform> for CastTarget {
185+
fn from(uniform: Uniform) -> CastTarget {
186+
CastTarget {
187+
prefix: [None; 8],
188+
prefix_chunk: Size::from_bytes(0),
189+
rest: uniform
190+
}
191+
}
192+
}
193+
194+
impl CastTarget {
195+
pub fn pair(a: Reg, b: Reg) -> CastTarget {
196+
CastTarget {
197+
prefix: [Some(a.kind), None, None, None, None, None, None, None],
198+
prefix_chunk: a.size,
199+
rest: Uniform::from(b)
200+
}
201+
}
202+
203+
pub fn size<C: HasDataLayout>(&self, cx: C) -> Size {
204+
(self.prefix_chunk * self.prefix.iter().filter(|x| x.is_some()).count() as u64)
205+
.abi_align(self.rest.align(cx)) + self.rest.total
206+
}
207+
208+
pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
209+
self.prefix.iter()
210+
.filter_map(|x| x.map(|kind| Reg { kind: kind, size: self.prefix_chunk }.align(cx)))
211+
.fold(cx.data_layout().aggregate_align.max(self.rest.align(cx)),
212+
|acc, align| acc.max(align))
213+
}
214+
}

src/librustc_target/abi/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ use spec::Target;
1616
use std::cmp;
1717
use std::ops::{Add, Sub, Mul, AddAssign, RangeInclusive};
1818

19+
pub mod call;
20+
1921
/// Parsed [Data layout](http://llvm.org/docs/LangRef.html#data-layout)
2022
/// for a target, which contains everything needed to compute layouts.
2123
pub struct TargetDataLayout {

src/librustc_target/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@
3131
#![feature(inclusive_range)]
3232
#![feature(slice_patterns)]
3333

34+
#[macro_use]
35+
extern crate bitflags;
3436
extern crate syntax;
35-
extern crate rand;
3637
extern crate serialize;
3738
#[macro_use] extern crate log;
3839

src/librustc_trans/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ crate-type = ["dylib"]
1010
test = false
1111

1212
[dependencies]
13-
bitflags = "1.0"
1413
cc = "1.0.1"
1514
flate2 = "1.0"
1615
jobserver = "0.1.5"

0 commit comments

Comments
 (0)