|
| 1 | +#[cfg(feature = "master")] |
| 2 | +use std::convert::TryInto; |
| 3 | + |
| 4 | +#[cfg(feature = "master")] |
| 5 | +use gccjit::CType; |
1 | 6 | use gccjit::{RValue, Struct, Type};
|
2 | 7 | use rustc_codegen_ssa::common::TypeKind;
|
3 | 8 | use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, TypeMembershipMethods};
|
@@ -121,19 +126,35 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
121 | 126 | }
|
122 | 127 |
|
123 | 128 | fn type_f16(&self) -> Type<'gcc> {
|
124 |
| - unimplemented!("f16_f128") |
| 129 | + #[cfg(feature = "master")] |
| 130 | + if self.supports_f16_type { |
| 131 | + return self.context.new_c_type(CType::Float16); |
| 132 | + } |
| 133 | + bug!("unsupported float width 16") |
125 | 134 | }
|
126 | 135 |
|
127 | 136 | fn type_f32(&self) -> Type<'gcc> {
|
| 137 | + #[cfg(feature = "master")] |
| 138 | + if self.supports_f32_type { |
| 139 | + return self.context.new_c_type(CType::Float32); |
| 140 | + } |
128 | 141 | self.float_type
|
129 | 142 | }
|
130 | 143 |
|
131 | 144 | fn type_f64(&self) -> Type<'gcc> {
|
| 145 | + #[cfg(feature = "master")] |
| 146 | + if self.supports_f64_type { |
| 147 | + return self.context.new_c_type(CType::Float64); |
| 148 | + } |
132 | 149 | self.double_type
|
133 | 150 | }
|
134 | 151 |
|
135 | 152 | fn type_f128(&self) -> Type<'gcc> {
|
136 |
| - unimplemented!("f16_f128") |
| 153 | + #[cfg(feature = "master")] |
| 154 | + if self.supports_f128_type { |
| 155 | + return self.context.new_c_type(CType::Float128); |
| 156 | + } |
| 157 | + bug!("unsupported float width 128") |
137 | 158 | }
|
138 | 159 |
|
139 | 160 | fn type_func(&self, params: &[Type<'gcc>], return_type: Type<'gcc>) -> Type<'gcc> {
|
@@ -161,6 +182,41 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
161 | 182 | typ
|
162 | 183 | }
|
163 | 184 |
|
| 185 | + #[cfg(feature = "master")] |
| 186 | + fn type_kind(&self, typ: Type<'gcc>) -> TypeKind { |
| 187 | + if self.is_int_type_or_bool(typ) { |
| 188 | + TypeKind::Integer |
| 189 | + } else if typ.get_pointee().is_some() { |
| 190 | + TypeKind::Pointer |
| 191 | + } else if typ.is_vector() { |
| 192 | + TypeKind::Vector |
| 193 | + } else if typ.dyncast_array().is_some() { |
| 194 | + TypeKind::Array |
| 195 | + } else if typ.is_struct().is_some() { |
| 196 | + TypeKind::Struct |
| 197 | + } else if typ.dyncast_function_ptr_type().is_some() { |
| 198 | + TypeKind::Function |
| 199 | + } else if typ.is_compatible_with(self.float_type) { |
| 200 | + TypeKind::Float |
| 201 | + } else if typ.is_compatible_with(self.double_type) { |
| 202 | + TypeKind::Double |
| 203 | + } else if typ.is_floating_point() { |
| 204 | + match typ.get_size() { |
| 205 | + 2 => TypeKind::Half, |
| 206 | + 4 => TypeKind::Float, |
| 207 | + 8 => TypeKind::Double, |
| 208 | + 16 => TypeKind::FP128, |
| 209 | + size => unreachable!("Floating-point type of size {}", size), |
| 210 | + } |
| 211 | + } else if typ == self.type_void() { |
| 212 | + TypeKind::Void |
| 213 | + } else { |
| 214 | + // TODO(antoyo): support other types. |
| 215 | + unimplemented!(); |
| 216 | + } |
| 217 | + } |
| 218 | + |
| 219 | + #[cfg(not(feature = "master"))] |
164 | 220 | fn type_kind(&self, typ: Type<'gcc>) -> TypeKind {
|
165 | 221 | if self.is_int_type_or_bool(typ) {
|
166 | 222 | TypeKind::Integer
|
@@ -210,6 +266,16 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
210 | 266 | unimplemented!();
|
211 | 267 | }
|
212 | 268 |
|
| 269 | + #[cfg(feature = "master")] |
| 270 | + fn float_width(&self, typ: Type<'gcc>) -> usize { |
| 271 | + if typ.is_floating_point() { |
| 272 | + (typ.get_size() * u8::BITS).try_into().unwrap() |
| 273 | + } else { |
| 274 | + panic!("Cannot get width of float type {:?}", typ); |
| 275 | + } |
| 276 | + } |
| 277 | + |
| 278 | + #[cfg(not(feature = "master"))] |
213 | 279 | fn float_width(&self, typ: Type<'gcc>) -> usize {
|
214 | 280 | let f32 = self.context.new_type::<f32>();
|
215 | 281 | let f64 = self.context.new_type::<f64>();
|
|
0 commit comments