1 ; RUN: llc -mattr=sram,addsubiw < %s -march=avr | FileCheck %s 2 3 @char = common global i8 0 4 @char.array = common global [3 x i8] zeroinitializer 5 @char.static = internal global i8 0 6 7 @int = common global i16 0 8 @int.array = common global [3 x i16] zeroinitializer 9 @int.static = internal global i16 0 10 11 @long = common global i32 0 12 @long.array = common global [3 x i32] zeroinitializer 13 @long.static = internal global i32 0 14 15 @longlong = common global i64 0 16 @longlong.array = common global [3 x i64] zeroinitializer 17 @longlong.static = internal global i64 0 18 19 define void @global8_store() { 20 ; CHECK-LABEL: global8_store: 21 ; CHECK: ldi [[REG:r[0-9]+]], 6 22 ; CHECK: sts char, [[REG]] 23 store i8 6, i8* @char 24 ret void 25 } 26 27 define i8 @global8_load() { 28 ; CHECK-LABEL: global8_load: 29 ; CHECK: lds r24, char 30 %result = load i8, i8* @char 31 ret i8 %result 32 } 33 34 define void @array8_store() { 35 ; CHECK-LABEL: array8_store: 36 ; CHECK: ldi [[REG1:r[0-9]+]], 3 37 ; CHECK: sts char.array+2, [[REG1]] 38 ; CHECK: ldi [[REG3:r[0-9]+]], 1 39 ; CHECK: ldi [[REG2:r[0-9]+]], 2 40 ; CHECK: sts char.array+1, [[REG2]] 41 ; CHECK: sts char.array, [[REG3]] 42 store i8 1, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @char.array, i32 0, i64 0) 43 store i8 2, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @char.array, i32 0, i64 1) 44 store i8 3, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @char.array, i32 0, i64 2) 45 ret void 46 } 47 48 define i8 @array8_load() { 49 ; CHECK-LABEL: array8_load: 50 ; CHECK: lds r24, char.array+2 51 %result = load i8, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @char.array, i32 0, i64 2) 52 ret i8 %result 53 } 54 55 define i8 @static8_inc() { 56 ; CHECK-LABEL: static8_inc: 57 ; CHECK: lds r24, char.static 58 ; CHECK: inc r24 59 ; CHECK: sts char.static, r24 60 %1 = load i8, i8* @char.static 61 %inc = add nsw i8 %1, 1 62 store i8 %inc, i8* @char.static 63 ret i8 %inc 64 } 65 66 define void @global16_store() { 67 ; CHECK-LABEL: global16_store: 68 ; CHECK: ldi [[REG1:r[0-9]+]], 187 69 ; CHECK: ldi [[REG2:r[0-9]+]], 170 70 ; CHECK: sts int+1, [[REG2]] 71 ; CHECK: sts int, [[REG1]] 72 store i16 43707, i16* @int 73 ret void 74 } 75 76 define i16 @global16_load() { 77 ; CHECK-LABEL: global16_load: 78 ; CHECK: lds r24, int 79 ; CHECK: lds r25, int+1 80 %result = load i16, i16* @int 81 ret i16 %result 82 } 83 84 define void @array16_store() { 85 ; CHECK-LABEL: array16_store: 86 87 ; CHECK: ldi [[REG1:r[0-9]+]], 204 88 ; CHECK: ldi [[REG2:r[0-9]+]], 170 89 ; CHECK: sts int.array+3, [[REG2]] 90 ; CHECK: sts int.array+2, [[REG1]] 91 92 ; CHECK: ldi [[REG1:r[0-9]+]], 187 93 ; CHECK: ldi [[REG2:r[0-9]+]], 170 94 ; CHECK: sts int.array+1, [[REG2]] 95 ; CHECK: sts int.array, [[REG1]] 96 97 98 ; CHECK: ldi [[REG1:r[0-9]+]], 221 99 ; CHECK: ldi [[REG2:r[0-9]+]], 170 100 ; CHECK: sts int.array+5, [[REG2]] 101 ; CHECK: sts int.array+4, [[REG1]] 102 store i16 43707, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @int.array, i32 0, i64 0) 103 store i16 43724, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @int.array, i32 0, i64 1) 104 store i16 43741, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @int.array, i32 0, i64 2) 105 ret void 106 } 107 108 define i16 @array16_load() { 109 ; CHECK-LABEL: array16_load: 110 ; CHECK: lds r24, int.array+4 111 ; CHECK: lds r25, int.array+5 112 %result = load i16, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @int.array, i32 0, i64 2) 113 ret i16 %result 114 } 115 116 define i16 @static16_inc() { 117 ; CHECK-LABEL: static16_inc: 118 ; CHECK: lds r24, int.static 119 ; CHECK: lds r25, int.static+1 120 ; CHECK: adiw r24, 1 121 ; CHECK: sts int.static+1, r25 122 ; CHECK: sts int.static, r24 123 %1 = load i16, i16* @int.static 124 %inc = add nsw i16 %1, 1 125 store i16 %inc, i16* @int.static 126 ret i16 %inc 127 } 128 129 define void @global32_store() { 130 ; CHECK-LABEL: global32_store: 131 ; CHECK: ldi [[REG1:r[0-9]+]], 187 132 ; CHECK: ldi [[REG2:r[0-9]+]], 170 133 ; CHECK: sts long+3, [[REG2]] 134 ; CHECK: sts long+2, [[REG1]] 135 ; CHECK: ldi [[REG1:r[0-9]+]], 221 136 ; CHECK: ldi [[REG2:r[0-9]+]], 204 137 ; CHECK: sts long+1, [[REG2]] 138 ; CHECK: sts long, [[REG1]] 139 store i32 2864434397, i32* @long 140 ret void 141 } 142 143 define i32 @global32_load() { 144 ; CHECK-LABEL: global32_load: 145 ; CHECK: lds r22, long 146 ; CHECK: lds r23, long+1 147 ; CHECK: lds r24, long+2 148 ; CHECK: lds r25, long+3 149 %result = load i32, i32* @long 150 ret i32 %result 151 } 152 153 define void @array32_store() { 154 ; CHECK-LABEL: array32_store: 155 ; CHECK: ldi [[REG1:r[0-9]+]], 102 156 ; CHECK: ldi [[REG2:r[0-9]+]], 85 157 ; CHECK: sts long.array+7, [[REG2]] 158 ; CHECK: sts long.array+6, [[REG1]] 159 ; CHECK: ldi [[REG1:r[0-9]+]], 136 160 ; CHECK: ldi [[REG2:r[0-9]+]], 119 161 ; CHECK: sts long.array+5, [[REG2]] 162 ; CHECK: sts long.array+4, [[REG1]] 163 ; CHECK: ldi [[REG1:r[0-9]+]], 27 164 ; CHECK: ldi [[REG2:r[0-9]+]], 172 165 ; CHECK: sts long.array+3, [[REG2]] 166 ; CHECK: sts long.array+2, [[REG1]] 167 ; CHECK: ldi [[REG1:r[0-9]+]], 68 168 ; CHECK: ldi [[REG2:r[0-9]+]], 13 169 ; CHECK: sts long.array+1, [[REG2]] 170 ; CHECK: sts long.array, [[REG1]] 171 ; CHECK: ldi [[REG1:r[0-9]+]], 170 172 ; CHECK: ldi [[REG2:r[0-9]+]], 153 173 ; CHECK: sts long.array+11, [[REG2]] 174 ; CHECK: sts long.array+10, [[REG1]] 175 ; CHECK: ldi [[REG1:r[0-9]+]], 204 176 ; CHECK: ldi [[REG2:r[0-9]+]], 187 177 ; CHECK: sts long.array+9, [[REG2]] 178 ; CHECK: sts long.array+8, [[REG1]] 179 store i32 2887454020, i32* getelementptr inbounds ([3 x i32], [3 x i32]* @long.array, i32 0, i64 0) 180 store i32 1432778632, i32* getelementptr inbounds ([3 x i32], [3 x i32]* @long.array, i32 0, i64 1) 181 store i32 2578103244, i32* getelementptr inbounds ([3 x i32], [3 x i32]* @long.array, i32 0, i64 2) 182 ret void 183 } 184 185 define i32 @array32_load() { 186 ; CHECK-LABEL: array32_load: 187 ; CHECK: lds r22, long.array+8 188 ; CHECK: lds r23, long.array+9 189 ; CHECK: lds r24, long.array+10 190 ; CHECK: lds r25, long.array+11 191 %result = load i32, i32* getelementptr inbounds ([3 x i32], [3 x i32]* @long.array, i32 0, i64 2) 192 ret i32 %result 193 } 194 195 define i32 @static32_inc() { 196 ; CHECK-LABEL: static32_inc: 197 ; CHECK: lds r22, long.static 198 ; CHECK: lds r23, long.static+1 199 ; CHECK: lds r24, long.static+2 200 ; CHECK: lds r25, long.static+3 201 ; CHECK: subi r22, 255 202 ; CHECK: sbci r23, 255 203 ; CHECK: sbci r24, 255 204 ; CHECK: sbci r25, 255 205 ; CHECK: sts long.static+3, r25 206 ; CHECK: sts long.static+2, r24 207 ; CHECK: sts long.static+1, r23 208 ; CHECK: sts long.static, r22 209 %1 = load i32, i32* @long.static 210 %inc = add nsw i32 %1, 1 211 store i32 %inc, i32* @long.static 212 ret i32 %inc 213 } 214 215 define void @global64_store() { 216 ; CHECK-LABEL: global64_store: 217 ; CHECK: ldi [[REG1:r[0-9]+]], 34 218 ; CHECK: ldi [[REG2:r[0-9]+]], 17 219 ; CHECK: sts longlong+7, [[REG2]] 220 ; CHECK: sts longlong+6, [[REG1]] 221 ; CHECK: ldi [[REG1:r[0-9]+]], 68 222 ; CHECK: ldi [[REG2:r[0-9]+]], 51 223 ; CHECK: sts longlong+5, [[REG2]] 224 ; CHECK: sts longlong+4, [[REG1]] 225 ; CHECK: ldi [[REG1:r[0-9]+]], 102 226 ; CHECK: ldi [[REG2:r[0-9]+]], 85 227 ; CHECK: sts longlong+3, [[REG2]] 228 ; CHECK: sts longlong+2, [[REG1]] 229 ; CHECK: ldi [[REG1:r[0-9]+]], 136 230 ; CHECK: ldi [[REG2:r[0-9]+]], 119 231 ; CHECK: sts longlong+1, [[REG2]] 232 ; CHECK: sts longlong, [[REG1]] 233 store i64 1234605616436508552, i64* @longlong 234 ret void 235 } 236 237 define i64 @global64_load() { 238 ; CHECK-LABEL: global64_load: 239 ; CHECK: lds r18, longlong 240 ; CHECK: lds r19, longlong+1 241 ; CHECK: lds r20, longlong+2 242 ; CHECK: lds r21, longlong+3 243 ; CHECK: lds r22, longlong+4 244 ; CHECK: lds r23, longlong+5 245 ; CHECK: lds r24, longlong+6 246 ; CHECK: lds r25, longlong+7 247 %result = load i64, i64* @longlong 248 ret i64 %result 249 } 250 251 define void @array64_store() { 252 ; CHECK-LABEL: array64_store: 253 ; CHECK: ldi [[REG1:r[0-9]+]], 34 254 ; CHECK: ldi [[REG2:r[0-9]+]], 17 255 ; CHECK: sts longlong.array+7, [[REG2]] 256 ; CHECK: sts longlong.array+6, [[REG1]] 257 ; CHECK: ldi [[REG1:r[0-9]+]], 68 258 ; CHECK: ldi [[REG2:r[0-9]+]], 51 259 ; CHECK: sts longlong.array+5, [[REG2]] 260 ; CHECK: sts longlong.array+4, [[REG1]] 261 ; CHECK: ldi [[REG1:r[0-9]+]], 102 262 ; CHECK: ldi [[REG2:r[0-9]+]], 85 263 ; CHECK: sts longlong.array+3, [[REG2]] 264 ; CHECK: sts longlong.array+2, [[REG1]] 265 ; CHECK: ldi [[REG1:r[0-9]+]], 136 266 ; CHECK: ldi [[REG2:r[0-9]+]], 119 267 ; CHECK: sts longlong.array+1, [[REG2]] 268 ; CHECK: sts longlong.array, [[REG1]] 269 store i64 1234605616436508552, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @longlong.array, i64 0, i64 0) 270 store i64 81985529216486895, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @longlong.array, i64 0, i64 1) 271 store i64 1836475854449306472, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @longlong.array, i64 0, i64 2) 272 ret void 273 } 274 275 define i64 @array64_load() { 276 ; CHECK-LABEL: array64_load: 277 ; CHECK: lds r18, longlong.array+16 278 ; CHECK: lds r19, longlong.array+17 279 ; CHECK: lds r20, longlong.array+18 280 ; CHECK: lds r21, longlong.array+19 281 ; CHECK: lds r22, longlong.array+20 282 ; CHECK: lds r23, longlong.array+21 283 ; CHECK: lds r24, longlong.array+22 284 ; CHECK: lds r25, longlong.array+23 285 %result = load i64, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @longlong.array, i64 0, i64 2) 286 ret i64 %result 287 } 288 289 define i64 @static64_inc() { 290 ; CHECK-LABEL: static64_inc: 291 ; CHECK: lds r18, longlong.static 292 ; CHECK: lds r19, longlong.static+1 293 ; CHECK: lds r20, longlong.static+2 294 ; CHECK: lds r21, longlong.static+3 295 ; CHECK: lds r22, longlong.static+4 296 ; CHECK: lds r23, longlong.static+5 297 ; CHECK: lds r24, longlong.static+6 298 ; CHECK: lds r25, longlong.static+7 299 ; CHECK: subi r18, 255 300 ; CHECK: sbci r19, 255 301 ; CHECK: sbci r20, 255 302 ; CHECK: sbci r21, 255 303 ; CHECK: sbci r22, 255 304 ; CHECK: sbci r23, 255 305 ; CHECK: sbci r24, 255 306 ; CHECK: sbci r25, 255 307 ; CHECK: sts longlong.static+7, r25 308 ; CHECK: sts longlong.static+6, r24 309 ; CHECK: sts longlong.static+5, r23 310 ; CHECK: sts longlong.static+4, r22 311 ; CHECK: sts longlong.static+3, r21 312 ; CHECK: sts longlong.static+2, r20 313 ; CHECK: sts longlong.static+1, r19 314 ; CHECK: sts longlong.static, r18 315 %1 = load i64, i64* @longlong.static 316 %inc = add nsw i64 %1, 1 317 store i64 %inc, i64* @longlong.static 318 ret i64 %inc 319 } 320 321 define i8 @constantaddr_read8() { 322 ; CHECK-LABEL: constantaddr_read8: 323 ; CHECK: lds r24, 1234 324 %1 = load i8, i8* inttoptr (i16 1234 to i8*) 325 ret i8 %1 326 } 327 328 define i16 @constantaddr_read16() { 329 ; CHECK-LABEL: constantaddr_read16: 330 ; CHECK: lds r24, 1234 331 ; CHECK: lds r25, 1235 332 %1 = load i16, i16* inttoptr (i16 1234 to i16*) 333 ret i16 %1 334 } 335 336 define void @constantaddr_write8() { 337 ; CHECK-LABEL: constantaddr_write8: 338 ; CHECK: sts 1234 339 store i8 22, i8* inttoptr (i16 1234 to i8*) 340 ret void 341 } 342 343 define void @constantaddr_write16() { 344 ; CHECK-LABEL: constantaddr_write16: 345 ; CHECK: sts 1235 346 ; CHECK: sts 1234 347 store i16 2222, i16* inttoptr (i16 1234 to i16*) 348 ret void 349 } 350